Awk 强制grep抓取匹配行两次
假设我有:Awk 强制grep抓取匹配行两次,awk,grep,duplicates,Awk,Grep,Duplicates,假设我有: Z 10 Z 11 Y 10 我用过: $ grep "Z" <above_file> -A 1 Z 10 Z 11 Y 10 本质上,如果grep看到下一行也与模式匹配,我希望它被复制。手动逐行检查或使用带条件的复杂awk语句是最佳/唯一的解决方案?此步骤后还有进一步的处理,但这是阻碍我前进的边缘案例。尝试: $ awk 'f{print; f=0} /Z/{print; f=1}' file Z 10 Z 11 Z 11 Y 10 工
Z 10
Z 11
Y 10
我用过:
$ grep "Z" <above_file> -A 1
Z 10
Z 11
Y 10
本质上,如果grep
看到下一行也与模式匹配,我希望它被复制。手动逐行检查或使用带条件的复杂awk
语句是最佳/唯一的解决方案?此步骤后还有进一步的处理,但这是阻碍我前进的边缘案例。尝试:
$ awk 'f{print; f=0} /Z/{print; f=1}' file
Z 10
Z 11
Z 11
Y 10
工作原理
Awk隐式地一次读取一行输入文件。脚本使用单个变量f
,如果前一行匹配Z
,则该变量为true(非零)
如果f{print;f=0}
为非零,则打印此行并设置f
f=0
如果此行与regex/Z/{print;f=1}
匹配,则打印此行并设置Z
f=1
请注意,无需初始化
f
。在awk中,未定义的变量默认为零(在数字上下文中)或空字符串(在字符上下文中)。在任何一种情况下,未定义的变量都是逻辑错误。也许这样也可以:
$ sed -n ':check /^Z/ {p; n; h; p; x; b check}' file
--:check
是分支标签,用于匹配/^Z/
的行(因此,从Z
开始)。sed
通过循环:
p
打印行(=打印匹配行)n
ext oneh
旧缓冲区p
打印它(=匹配后打印行)x
更改行,即将h
旧缓冲区移回(=在匹配一行后返回行)b
ranch tocheck
如果行与^Z
匹配,则重复整个过程(=检查)sed
应该适合这种递归(sed
不存储任何堆栈,对吧?),但它可能不是。
另外,我不确定脚本是否正确:)f是否自动初始化为非零?@TriHard8是。在awk中,未定义的变量默认为零(在数字上下文中)或空字符串(在字符上下文中)。无论哪种情况,未定义的变量都是logical-false。谢谢,我明天在办公室时会检查。我喜欢sed和awk命令,因为我只是在学习它们。不过有一个问题……例如,我是否需要键入
print
您的p
位置和next
您的n
位置?或者sed会自动识别这些标志吗?@TriHard8不,事实上,你不能像print
那样键入一个完整的单词——所有sed的命令都是一个字母。尽管这些字母是描述命令的单词的助记符:p
用于打印,s
用于替换等,还有一点关于大sed教程的广告:由Bruce Barnett编写。他在AWK上也有一个。
$ sed -n ':check /^Z/ {p; n; h; p; x; b check}' file