Правильно избегать строк sed - PullRequest
10 голосов
/ 16 января 2010

У меня есть регулярное выражение и шаблон замены, которые были протестированы в Notepad ++ на моих входных данных и работают правильно. Однако, когда я выражаю их в выражении sed, ничто не соответствует.

Вот команда sed:

 # SEARCH = ([a-zA-Z0-9.]+) [0-9] (.*)
 # REPLACE = \2 (\1)

 sed -e 's/\([a-zA-Z0-9.]+\) [0-9] \(.*\)/\2 \(\1\)/g'

Вот выборка данных:

jdoe 1 Doe, John
jad 1 Doe, Jane
smith 2 Smith, Jon

и желаемый результат:

Doe, John  (jdoe)
Doe, Jane  (jad)
Smith, Jon (smith)

Я попытался удалить и добавить escape-символы к различным символам в выражении sed, но либо ничего не найдено, либо что-то вроде:

sed: -e expression #1, char 42: invalid reference \2 on `s' command's RHS

Как я могу правильно избежать этого?

Ответы [ 5 ]

17 голосов
/ 16 января 2010

Обычно мне проще использовать ключ -r, поскольку это означает, что экранирование аналогично большинству других языков:

sed -r 's/([a-zA-Z0-9.]+) [0-9] (.*)/\2 (\1)/g' file1.txt
9 голосов
/ 16 января 2010

Несколько предупреждений и дополнений к тому, что уже говорили все остальные:

  1. Опция -r является расширением GNU для включения расширенных регулярных выражений. BSD использует sed вместо -E.
  2. Sed и Grep использование Основные регулярные выражения
  3. Awk использует Расширенные регулярные выражения
  4. Вы должны освоиться с спецификациями POSIX , такими как IEEE Std 1003.1 , если вы хотите писать переносимые сценарии, make-файлы и т. Д.

Я бы порекомендовал переписать выражение как

's/\([a-zA-Z0-9.]\{1,\}\) [0-9] \(.*\)/\2 (\1)/g'

, который должен делать именно то, что вы хотите в любом POSIX-совместимом sed. Если вы действительно заботитесь о таких вещах, рассмотрите определение переменной среды POSIXLY_CORRECT.

4 голосов
/ 16 января 2010

Знак плюс необходимо экранировать, если не используется переключатель -r.

2 голосов
/ 16 января 2010

Использование awk намного проще ...:

cat test.txt | awk '{ print $3 " " $4 " " "("$1")" }'

Выход:

Doe, John (jdoe)
Doe, Jane (jad)
Smith, Jon (smith)

см. Человек awk 1

1 голос
/ 16 января 2010
$ sed -e 's/\([a-zA-Z0-9.].*\) [0-9] \(.*\)/\2 \(\1\)/g' file
Doe, John (jdoe)
Doe, Jane (jad)
Smith, Jon (smith)
...