GNU sed单进程内如何让插入换行后的新行被后续表达式识别?
解决GNU sed中插入换行后无法处理新行的问题
问题出在sed的工作机制上:sed默认一次读取一整行到「模式空间」里处理,你用s命令插入的换行符只是模式空间里的普通字符,并不会让sed把模式空间拆分成多个独立的逻辑行。所以第二个表达式/^[^a]/d是对整个模式空间的内容做匹配(比如原行是x a y,替换后模式空间是x \na y,整个内容的开头是x,符合^[^a],直接被全删了),自然没输出。
要在单sed进程里让插入的换行成为可独立处理的真实行,得手动把模式空间里的内容按换行拆分,逐行处理。用GNU sed的P和D命令配合循环就能实现:
sed -e 's/\ba\b/\n&/g' -e ':split' -e '/\n/{P;D}' -e '/^[^a]/d' lines
命令拆解:
s/\ba\b/\n&/g:和你原来的操作一样,在每个独立单词a前插入换行符。:split:定义一个循环标签,用来重复处理模式空间里的内容。/\n/{P;D}:如果模式空间里包含换行符:P:打印换行符之前的部分(相当于把拆分出的第一行输出)D:删除换行符之前的部分,然后回到split标签继续处理剩下的内容
/^[^a]/d:当模式空间里没有换行符时(也就是处理到最后一段内容),如果它不是以a开头,就删除它。
这样处理后,插入的换行符就会被拆分成独立的行,后续的过滤表达式就能正确作用在每一行上,效果和你用两个sed串联完全一致。
内容的提问来源于stack exchange,提问作者umläute
相关产品推荐
相关产品推荐

