我有一个名为"a6s"的文本文件,其中包含多行内容:
y
n
yyy
n
y
yyy
yy
y
yyy
n
我使用了这个脚本:
$ sed -i "s/y$^y/ya\ny/g" a6s;
我希望在上一行结尾和下一行开头的两个“y”字符之间插入内容以输出:
y
n
yyy
n
ya
yyya
yya
ya
yyy
n
使用GNU sed
(感谢@Sundeep提供的完美解决方案):
sed -i '/y$/ {N; s/y\ny/ya\ny/; P; D}' a6s
sed
,您需要使用N
、P
和D
命令:
{cmds}
:一组命令/y$/ {cmds}
:只有当行以y
结尾时才执行命令组N
:读取下一行到模式空间s/regex/replacement/
:进行替换,不需要g
标志P
:打印模式空间直到第一个\n
字符(第一行)D
:删除模式空间直到第一个\n
字符我的原始解决方案使用了不必要的标签:
sed -i ':a; N; s/y\ny/ya\ny/; {P; D}; ba' a6s
sed 'N;s/y\ny/ya\ny/;P;D' file
就足够了? - potong/$y/
只有在不需要它们的情况下才会跳过命令 :) - PesaThesed只能对单个行进行简单替换,仅此而已。当你试图用它做其他任何事情时,你就在使用过时的符文,在20世纪80年代中期发明awk后就变得多余了。使用GNU awk进行多字符RS操作:
$ awk -v RS='^$' -v ORS= '{while(sub(/y\ny/,"ya\ny"));} 1' file
y
n
yyy
n
ya
yyya
yya
ya
yyy
n
y\ny
替换为ya\ny
,直到没有要替换的y\ny
。sed -z ':a s/y\ny/ya\ny/g; ta'
(假设输入没有 NUL 字符)... 你不能在这里使用 gsub,因为一旦 y\ny
被替换,第二个 y
就不会再与下一行匹配。 - Sundeepy\ny\ny
它不会正确工作,明白了,谢谢 :) - PesaThesed 's/yy/yay/g'
不会将 yyy
更改为 yayay
,您需要 sed 's/yy/yay/g; s/yy/yay/g'
才能实现。因此,我本可以使用 gsub(),但它不会完成每个替换,我需要循环或两次调用才能完成,因此我决定使用循环来避免冗余,并且当您有循环时,sub() 与 gsub() 一样好,并且在我看来更清晰。 - Ed Mortony\n(?=y)
末尾的字符串y
不会成为正则表达式匹配的一部分,但我不确定如何表述我的前面陈述,以更清楚地表达我正在谈论的是包含在正则表达式匹配中的字符串,而不仅仅是说这个正则表达式。我怀疑这个观点已经被表达了。 - Ed Morton/s
或一些笑脸.. - Sundeep将输入文件转换为一行并不是一个简单的解决方案:您需要对文件进行两次处理:
tr '\n' '\r' < a6s | sed ':a;s/y\ry/ya\ry/g;ta' | tr '\r' '\n'
or
tr '\n' '\r' < a6s | sed 's/y\ry/ya\ry/g;s/y\ry/ya\ry/g' | tr '\r' '\n'