给定以下输入文件:
text
text
pattern2
pattern3
text
text
pattern1
pattern2
pattern3
pattern2
pattern3
pattern2
pattern3
text
text
我需要搜索“pattern1”,然后我需要分别用“pattern2-new”和“pattern3-new”替换第一次出现的“pattern2”和“pattern3”,并删除所有其他出现的“pattern2”和“模式 3”。我追求的最终结果是:
text
text
pattern2
pattern3
text
text
pattern1
pattern2-new
pattern3-new
text
text
起初我以为我可以通过选择以“pattern1”开头并以“pattern3”结尾的行范围然后使用c命令替换整个范围但是sed中的范围选择是非贪婪的所以赢了工作。但是,我仍然可以使用 sed 进行替换,但需要想出另一种方法来删除“pattern1”之后出现的所有其他“pattern2”和“pattern3”。
使事情复杂化的是,它在 busybox 环境中运行,因此无法访问 perl 或大多数其他奇特的工具。基本上 sed、awk 和 grep 是我能想到的唯一支持 busybox 的文件/字符串操作工具。
与awk:
$ awk '
BEGIN{l=1}/^pattern1/{print;l=0;print "pattern2-new";print "pattern3-new";next}
!/^pattern/{l=1}l' file
text
text
pattern2
pattern3
text
text
pattern1
pattern2-new
pattern3-new
text
text
假设:
pattern1
将匹配行 = this is a line with pattern11111
的位置,否则可以添加额外的逻辑,但我们需要一个更具代表性的 OP 真实数据示例-new
的行上,我们只附加到该行的第一个匹配项(例如,如果line = pattern2 pattern2
then newline = pattern2-new pattern2
),否则sub()
可以替换为gsub()
附加到行中的所有实例一个(冗长)
awk
想法:
awk '
/pattern1/ { replace2=replace3=1 }
/pattern2/ && remove2 { next }
/pattern2/ && replace2 { sub(/pattern2/,"pattern2-new"); remove2=1 }
/pattern3/ && remove3 { next }
/pattern3/ && replace3 { sub(/pattern3/,"pattern3-new"); remove3=1 }
1
' patterns.txt
这会产生:
text
text
pattern2
pattern3
text
text
pattern1
pattern2-new
pattern3-new
text
text