我想捕获变量中的 \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
的环境变量,并在 的内容中每次出现 之前插入该变量的内容。perl
perl
pattern
abc.txt
要在类似 Bourne 的 shell 中将x
除变量之外的任何字符分配给任何字符,您可以使用:'
a='x'
所以对于反斜杠:
a='\'
对于换行符:
a='
'
对于像换行符这样的控制字符,但是对于退格键或回车符来说情况会更糟,这会使代码不太清晰。
ksh93 引入了一种新$'...'
形式的引号来以转义形式指定这些字符。其他 shell,如bash
、zsh
或mksh
FreeBSDsh
已经复制并扩展了它(如$'\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