如何在模式前插入反斜杠和换行符?

如何在模式前插入反斜杠和换行符?

我想捕获变量中的 \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 的 shell 中

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

将传递一个包含换行符a的环境变量,并在 的内容中每次出现 之前插入该变量的内容。perlperlpatternabc.txt

要在类似 Bourne 的 shell 中将x除变量之外的任何字符分配给任何字符,您可以使用:'

a='x'

所以对于反斜杠:

a='\'

对于换行符:

a='
'

对于像换行符这样的控制字符,但是对于退格键或回车符来说情况会更糟,这会使代码不太清晰。

ksh93 引入了一种新$'...'形式的引号来以转义形式指定这些字符。其他 shell,如bashzshmkshFreeBSDsh已经复制并扩展了它(如$'\uXXXX'由 添加的形式zsh)。

在这些 shell 中,您可以使用:

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

指定换行符、退格符、回车符、反斜杠或单引号字符。

该引用运算符还不是标准的,因此您不能在可移植sh脚本中使用它。标准替代方案是使用:

a=$(printf '\b')

例如,对于退格键,但这不适用于换行符,因为命令替换 ( $(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

相关内容