我有一个文本文件,其中有几行。我想做的是找到所有与模式匹配的行,如果在它们之前没有换行符(=非空行),请创建它。 这样的东西,但是不能正常工作:
sed -i '/[a-zA-Z0-9]/{N;/PATTERN/{s/PATTERN/\nPATTERN/}}' FILENAME
我知道用awk或perl / bash可以更轻松,更轻松地完成此操作,但是我更喜欢单行/一步的解决方案。
样本输入文件:
LINE1
LINE2
PATTERN
LINE3
PATTERN
LINE4
预期输出:
LINE1
LINE2
PATTERN
LINE3
PATTERN
LINE4
答案 0 :(得分:1)
我不太擅长sed,但是这是我在awk中的方法:
awk 'prev != "" && /PATTERN/ { print "" } { prev = $0; print }' file
如果prev
(上一行)不为空并且当前行与/PATTERN/
相匹配,则打印空白行。无条件地保存当前行以便与下一行以及print
当前行进行比较。
要实现“就地”编辑(如sed -i
),只需将命令重定向到一个临时文件,然后覆盖原始文件:
awk 'prev != "" && /PATTERN/ { print "" } { prev = $0; print }' file > tmp && mv tmp file
请注意,由于最初未设置prev
,因此即使第一行与/PATTERN/
相匹配,此也不会在输出的开头打印换行符。要解决此问题,您可以将条件更改为:
(NR == 1 || prev != "") && /PATTERN/
您还可以使用-i inplace
选项,使用GNU awk实现就地编辑。
答案 1 :(得分:1)
看看这个GNU sed
(注意,awk
是工作的更好工具):
sed -i '/PATTERN/{x;/^$/!i\
x};h' input
h
是将模式空间的内容保存到保持缓冲区的命令。它将在每个循环结束时保存该行,以便在下一个循环中将其用作“上一个”行
x
交换保留空间和模式空间的内容。只要当前行与您的/PATTERN/
相匹配,就会将先前保存的行放入模式空间。如果前一行 NOT 为空(/^$/!
),则使用i
命令插入换行符。然后使用x
命令将当前行放回模式空间
如果即使第一行与/PATTERN/
相匹配,也要添加换行符,请使用:
sed -i '/PATTERN/{1h;x;/^$/! ...
进一步阅读: