如何使用SED在3个连续模式后插入关键字
下面的示例给出了所需的结果,但它适用于连续和非连续模式搜索 我只需要对连续的模式使用这个逻辑 每连续出现3次苹果后,应插入橙色如何使用SED在3个连续模式后插入关键字,sed,Sed,下面的示例给出了所需的结果,但它适用于连续和非连续模式搜索 我只需要对连续的模式使用这个逻辑 每连续出现3次苹果后,应插入橙色 sed "/APPLE/{p;s/.*/1/;H;g;/^\(\n1\)\{3\}$/s//ORANGES/p;d}" < input.txt > output.txt 电流输出 APPLE APPLE APPLE ORANGE APPLE APPLE APPLE ORANGE APPLE APPLE MANGO APPLE ORANG
sed "/APPLE/{p;s/.*/1/;H;g;/^\(\n1\)\{3\}$/s//ORANGES/p;d}" < input.txt > output.txt
电流输出
APPLE
APPLE
APPLE
ORANGE
APPLE
APPLE
APPLE
ORANGE
APPLE
APPLE
MANGO
APPLE
ORANGE -------->>> NOT NEEDED <<
APPLE
苹果公司
苹果
苹果
橙色
苹果
苹果
苹果
橙色
苹果
苹果
芒果
苹果
橙色---------------->>>不需要
每连续出现3次苹果后,应插入橙色
sed "/APPLE/{p;s/.*/1/;H;g;/^\(\n1\)\{3\}$/s//ORANGES/p;d}" < input.txt > output.txt
以下脚本:
#!/bin/bash
cat <<EOF |
APPLE
APPLE
APPLE
APPLE
APPLE
APPLE
APPLE
APPLE
MANGO
APPLE
APPLE
APPLE
EOF
sed '
# Add to hold space and inspect hold space
H
x
/^\(\nAPPLE\)\{3\}$/{
# 3 apples in hold space, means we add orange to pattern space
# and clear hold space
s///
x
s/$/\nORANGE/
x
}
# There are at least 3 lines in hold space
/^\(\n[^\n]*\)\{3\}/{
# Remove first line from hold space
s/\n[^\n]*//
}
x
'
这可能适用于您(GNU-sed):
这将在连续的3行之后附加一行ORANGE
,其中包含字符串APPLE
要为n条连续线(例如5条)参数化上述解决方案,请使用:
另一种选择:
sed '/APPLE/!b;:a;N;/\n[^\n]*APPLE[^\n]*$/!b;s/[^\n]*/&/3;Ta;a\ORANGE' file
如果要追加的值是变量,请使用:
sed '/APPLE/!b;:a;N;/\n[^\n]*APPLE[^\n]*$/!b;s/[^\n]*/&/3;Ta;a\'"$var" file
欢迎来到SO,感谢您展示您的努力,请在您的问题中添加输入和预期输出的示例,以使其更清楚,谢谢。它必须是
sed
?为什么不使用另一种更简单的工具呢?如果是,为什么不是python、perl或ruby?/^\(\n1\){3\}$
为什么要检查是否有3个呢?@KamilCuk,谢谢你的回答,这里的要求仅限于与shell脚本一起使用,而不是perl或ruby。是否可以编辑/修改以下脚本以满足使用shell脚本的sed“/APPLE/{p;s/*/1/;H;g;/^(\n1)\{3\}$/s//ORANGES/p;d}”,但sed不是shell脚本。Sed是一个外部程序,比如perl和ruby。感谢您在@potong给出的答案,如果您能向我解释这个脚本的工作原理,特别是{2..5}的用途,我将不胜感激used@Ankur第一个解决方案是连续3行,硬编码此n;/!b
在溶液中填充两次图案。第二种解决方案是,使用$(…)
的插值将此硬代码编程到sed程序中,同时在其中运行代码并将其替换到sed程序中printf
将打印n;//!b如果有四个参数,则执行四次{2..5}
转换为2 3 4 5
,%.0s
模板接受这些参数(零宽度)。因此,代码printf'n;//!b、 %。0s'{2..5}
转换为n;//!Bn、 //!Bn、 //!Bn、 //!b代码>。谢谢@potong的解释,你的备选脚本按照我需要的方式工作。但是还有一件小事情仍然没有完成,我不知道为什么会发生这种情况。。。在实际场景中,我试图通过下面的变量===pattern=orange sed'/APPLE/访问模式值(在本例中为橙色)!b、 :A.N/\n[^\n]*苹果[^\n]*$/!Bs/[^\n]*/&/3;助教;a\${pattern}'==但尽管打印橙色,它还是在output@Ankursed程序用单引号括起来,这不会插入shell变量。要允许这样做,只需用单引号括起来变量即可。但是,由于变量是程序的最后一部分,所以只需删除最后一个单引号并将其插入变量之前。请参见编辑。
sed '/APPLE/!b;'$(printf 'n;//!b;%.0s' {2..5})'a\ORANGE' file
sed '/APPLE/!b;:a;N;/\n[^\n]*APPLE[^\n]*$/!b;s/[^\n]*/&/3;Ta;a\ORANGE' file
sed '/APPLE/!b;:a;N;/\n[^\n]*APPLE[^\n]*$/!b;s/[^\n]*/&/3;Ta;a\'"$var" file