#bash #shell #unix #awk #sed
#bash #оболочка #unix #awk #sed
Вопрос:
У меня есть файл (тест) со следующим содержимым, которое необходимо отредактировать.
тест
foo:
bar:hello
В настоящее время я использую sed для сопоставления с шаблоном и добавления строки в конец строки.
sed -ie "/^bar/ s/$/,there" test
Что дает мне ожидаемый результат, т.е.
foo:
bar:hello,there
Но проблема в том, что запятая (,) должна быть там, когда строка не заканчивается :
. иначе это становится похоже:
sed -ie "/^foo/ s/$/,there" test
Вывод:
foo:,there
bar:hello
Требование:
foo:there
bar:hello
Итак, возможно ли каким-либо образом проверить наличие шаблона, после проверки соответствия последнему символу строки, в зависимости от последнего символа, добавить строку в конец строки.
PS: я не могу установить отдельный пакет.
Комментарии:
1. Если вы хотите добавить «there» к строке «foo:», то зачем вообще проверять наличие «bar»?
2. это «foo» или «bar» поступает в качестве входных данных. Итак, я получаю его в переменной и использую эту переменную внутри sed.
Ответ №1:
Сохраняйте простоту и просто используйте awk:
$ awk '/^foo/{$0 = $0 (/:$/ ? "" : ",") "there"} 1' file
foo:there
bar:hello
$ awk '/^bar/{$0 = $0 (/:$/ ? "" : ",") "there"} 1' file
foo:
bar:hello,there
Обратите внимание, что все исходные строки ( foo
or bar
), the :
, the ,
, the $
и заменяющий текст ( there
) указаны только один раз? Это одна из вещей, которые вы хотите в программном обеспечении — минимальная избыточность.
Вышеуказанное будет работать с использованием любого awk в любой оболочке в любом UNIX-блоке.
Комментарии:
1. хотя ответ проще, чем sed, awk выполняет дополнительную работу по записи изменений в тот же файл, в то время как с sed это проще.
2. @RatDon точно так же, как и в GNU sed
-i
, GNU awk должен-i inplace
делать то же самое.
Ответ №2:
Вот один из способов использования t
после успешной замены для перехода от второй s///
команды:
$ cat test
foo:
bar:
bar:hello
bar:
bar:hello
bar:
bar:hello
$ sed '/^bar/ {s/:$/:there/;t;s/$/, there/}' test
foo:
bar:there
bar:hello, there
bar:there
bar:hello, there
bar:there
bar:hello, there
Ответ №3:
Шаблоны перед вашими командами sed — это ваши условия. Вы должны знать, что вы можете указать несколько команд -e для sed.
Вот ваш код снова, но я игнорирую foo и bar . Я обращаю внимание только на последний символ:
sed -i -e '/[^:]$/s/$/,there/' -e '/:$/s/$/there/' test
/[^:]$/ — это любой символ, который не является двоеточием в конце строки. /:$/ — это дополнение (любая строка, заканчивающаяся двоеточием).
Вот результаты:
$ sed -e '/[^:]$/s/$/,there/' -e '/:$/s/$/there/' test
foo:there
bar:hello,there
Ответ №4:
попробуйте gnu sed для обоих,
sed -E '/^(foo|bar)/ s/:$/amp;there/;n; s/[^:]$/amp;,there/' test