У меня есть regex и заменяющий шаблон, которые были и протестированы в Блокноте ++ на моих входных данных и работе правильно. Когда я поместил их в 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
Как я могу добраться, это вышло правильно?
Обычно мне проще использовать переключатель -r, так как это означает, что экранирование похоже на большинство других языков:
sed -r 's/([a-zA-Z0-9.]+) [0-9] (.*)/\2 (\1)/g' file1.txt
Несколько предупреждений и дополнений к тому, что все уже сказали:
-r
является расширением GNU для включения расширенных регулярных выражений. Вместо этого BSD производное sed использует -E
. Я бы рекомендовал переписать выражение как
's/\([a-zA-Z0-9.]\{1,\}\) [0-9] \(.*\)/\2 (\1)/g'
, которое должно делать именно то, что вы хотите в любом POSIX-совместимом sed
. Если вы действительно заботитесь о таких вещах, подумайте об определении переменной окружения POSIXLY_CORRECT
.
Знак плюс необходимо сбежать, когда не используете коммутатор -R
.
$ sed -e 's/\([a-zA-Z0-9.].*\) [0-9] \(.*\)/\2 \(\1\)/g' file
Doe, John (jdoe)
Doe, Jane (jad)
Smith, Jon (smith)
Использование awk намного проще ...:
cat test.txt | awk '{ print $3 " " $4 " " "("$1")" }'
Выход:
Doe, John (jdoe)
Doe, Jane (jad)
Smith, Jon (smith)
См. Человек awk 1