Как вставить обратную косую черту и новую строку перед шаблоном?

Как вставить обратную косую черту и новую строку перед шаблоном?

Я хотел захватить \n в переменной (предположим a) и подставить $a перед шаблоном поиска в файле (abc.txt)

может ли кто-нибудь подсказать мне решение?

> cat abc.txt
hi how are you how is your health
> echo $a
\

ожидаемый результат (шаблон поиска - how)

hi \
how are you \
how is your health

решение1

В оболочке типа Bourne или rc

a='
' perl -pe 's/pattern/$ENV{a}$&/g' < abc.txt

передаст aпеременную окружения , perlсодержащую символ новой строки, и perlвставит содержимое этой переменной перед каждым вхождением patternв содержимом abc.txt.

Чтобы присвоить любой символ, xотличный 'от переменной в оболочках типа Bourne, можно использовать:

a='x'

Итак, для обратного слеша:

a='\'

Для новой строки:

a='
'

Для управляющих символов, таких как новая строка, но это было бы еще хуже, например, для забоя или возврата каретки, поскольку это делает код менее разборчивым.

ksh93 ввел новую $'...'форму кавычек для указания этих символов в экранированной форме. Другие оболочки, такие как bash, zsh, mkshили FreeBSD shскопировали и расширили (как $'\uXXXX'форма, добавленная zsh) ее с тех пор.

В этих оболочках вы можете использовать:

a=$'\n' a=$'\b' a=$'\r' a=$'\\' a=$'\''

Для назначения символа новой строки, возврата на одну позицию, возврата каретки, обратной косой черты или одинарной кавычки.

Этот оператор цитирования пока не является стандартным, поэтому вы не можете использовать его в переносимом shскрипте. Стандартной альтернативой является использование:

a=$(printf '\b')

для backspace например, но это не работает для новой строки, так как подстановка команд ( $(cmd)) удаляет конечные символы новой строки из вывода cmd. Приходится прибегать к таким хакам, как:

nl=$(printf '\n.'); nl=${nl%.}

(то есть добавить .и удалить его потом), чтобы сохранить его.

Обратите внимание, что он perlтакже понимает эти \nобозначения в своем коде, поэтому вы можете сделать следующее:

perl -pe 's/pattern/\n$&/g' < abc.txt

Реализация GNU sed(и несколько других в настоящее время) также поддерживают это:

sed 's/pattern/\n&/g' < abc.txt

но это не стандарт. Стандартно, новая строка в заменяющей части команды sдолжна sedбыть выражена обратной косой чертой, за которой следует фактически новая строка, так что это будет:

backslash='\' newline='
'
sed "s/pattern/$backslash$newline&/g" < abc.txt

Или без переменных:

sed 's/pattern/\
&/g' < abc.txt

Итак, если вы хотите вставить и обратную косую черту, и новую строку перед pattern, вам нужно:

sed 's/pattern/\\\
&/g' < abc.txt

Всего 3 обратных слеша, два для буквального обратного слеша и один для новой строки. Или с помощью perl:

perl -pe 's/pattern/\\\n$&/g' < abc.txt

Или с вашей aпеременной:

a='\
' perl -pe 's/pattern/$ENV{a}$&/g' < abc.txt

решение2

Вы также можете использовать собственные команды bash, используя:

cat abc.txt | sed -e 's/how/\nhow/g' |  while read line; do echo "$line \\"; done

Связанный контент