#bash #macos #sed
#bash #macos #sed
Вопрос:
В моем случае я хочу разделить одну строку на слова с помощью команды sed, как показано ниже, хотя я думаю, что все должно работать.
[heping@Laputa:~]$echo "abc def gks dps" | sed "s/s /n/g"
abc def gks dps
[heping@Laputa:~]$echo "abc def gks dps" | sed "s/s{1,}/n/g"
abc def gkn dpn
[heping@Laputa:~]$echo "abc def gks dps" | sed "s/ {1,}/n/g"
abcndefngksndps
[heping@Laputa:~]$echo "abc def gks dps" | sed "s/ {1,}/:/g"
abc:def:gks:dps
[heping@Laputa:~]$echo "abc def gks dps" | sed "s/ /:/g"
abc def gks dps
Но на самом деле работает только одно.
[heping@Laputa:~]$echo "abc def gks dps" | sed "s/ {1,}/:/g"
abc:def:gks:dps
Похоже, что s
набор символов и
специальный символ в регулярном выражении плохо работают с командой sed. И n
не распознается как новая строка. Кто-нибудь может сказать мне, почему или дать какую-нибудь подсказку. Спасибо.
Ответ №1:
sed соответствует базовым регулярным выражениям, в то время как мета-символ
взят из расширенных регулярных выражений. Сокращение s
для символьного класса POSIX [[:space:]]
будет работать только в некоторых sed (например, GNU sed) в качестве расширения. Аналогично n
будет работать только в значении «новая строка» в некоторых sed, в то время как в любом sed вы можете использовать обратную косую черту, за которой следует буквальный символ новой строки. Использование double ( "
) вместо одинарных кавычек ( '
) вокруг вашего скрипта подвергает его воздействию оболочки и, следовательно, требует дополнительных экранирований обратной косой черты — всегда используйте одинарные кавычки вокруг строк или скриптов, если у вас нет особой потребности в двойных кавычках (например, для расширения переменной), и используйте double, только если у вас нет особой необходимости в none (например, для разрешения расширения с помощью подстановочных знаков).
Чтобы делать то, что вы хотите в любом POSIX sed, нужно:
$ echo 'abc def gks dps' | sed 's/[[:space:]][[:space:]]*/
/g'
abc
def
gks
dps
но это будет работать с GNU sed (обратите внимание на -E
включение ERES для
— это поддерживается в GNU sed и OSX / BSD sed, но из этих 2 sed только GNU sed будет поддерживать s
и n
):
$ echo 'abc def gks dps' | sed -E 's/s /n/g'
abc
def
gks
dps
Комментарии:
1. Вау, твой ответ больше похож на стандартное руководство для новичка вроде меня! Спасибо. Я постараюсь предпочесть одинарные кавычки двойным кавычкам.
Ответ №2:
Существует несколько проблем. Прежде всего, sed
по умолчанию используются базовые регулярные выражения, которые не распознаются
. Используйте -E
модификатор для расширенных регулярных выражений, которые работают.
Во-вторых, sed
не распознается n
; но вы можете использовать цитирование ANSI C, чтобы bash
это было понятно. Однако, если вы просто используете n
, у вас будет просто разрыв строки в вашем sed
шаблоне, поэтому вам придется экранировать разрыв строки, чтобы sed
использовать его буквально; таким образом, вам нужно \
для экранирования и n
для разрыва строки в общей сложности три обратных косых черты.
Наконец, s
класс символов также не распознается vanilla sed
(но он доступен в GNU sed
, который используется дистрибутивами Linux). Вместо этого используйте буквенный пробел, если вам нужна совместимость, например, с OSX (или brew install gnu-sed
).
echo "abc def gks dps" | sed -E $'s/ /\n/g'
# => abc
# def
# gks
# dps
Комментарии:
1. Сэр, спасибо за ваше определенно четкое объяснение. Но s не поддерживается, это is….is странно.
2. Позвольте мне перефразировать:
s
поддерживается вgsed
(GNUsed
, которая по умолчаниюsed
установлена в Linux). Это не поддерживается на более старых,sed
таких, например, как тот, который поставляется с OSX по умолчанию.sed
имеет очень, очень долгую историю. Я отредактирую это в…3. Хорошо, я понял. И еще один вопрос: зачем использовать доллар и одинарную кавычку? и особенно почему доллар? Я пытаюсь изменить его на sed -E «s / / \ n / g», и это становится хреновым. : )
4. $ thing — это инструкция bash, указывающая bash заменить строку
n
(или любую другую escape-последовательность) в том, что следует между'
s, буквальным переводом строки, прежде чем sed увидит скрипт. Итак, bash преобразует\n
в<newline>
, а затем sed видит всю команду целиком, посколькуs/ /<newline>/g'
я бы не рекомендовал оборачивать весь скрипт таким образом, просто делайте это, когда абсолютно необходимо, для максимально краткого раздела, в данном случаеsed -E 's/ /'$'n''/g'
чтобы просто позволитьn
развернуться до буквального перевода строки, но не предоставлять остальную часть скрипта оболочке.5. Спасибо, сэр. Для меня это новый способ ввода символа новой строки в командную строку оболочки. Прежде чем вы мне это скажете, я много лет использовал одинарную кавычку для ввода символа новой строки в оболочку. Большое вам спасибо. : )