用 BusyBox 贪婪地替换多行

问题描述 投票:0回答:2

给定以下输入文件:

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 的文件/字符串操作工具。

bash sed replace busybox
2个回答
0
投票

$ 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

0
投票

假设:

  • 我们有兴趣匹配行中任何位置的“模式”,例如,
    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
© www.soinside.com 2019 - 2024. All rights reserved.