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

  • /Z/{print;f=1}

    如果此行与regex
    Z
    匹配,则打印此行并设置
    f=1


请注意,无需初始化
f
。在awk中,未定义的变量默认为零(在数字上下文中)或空字符串(在字符上下文中)。在任何一种情况下,未定义的变量都是逻辑错误。

也许这样也可以:

$ sed -n ':check /^Z/ {p; n; h; p; x; b check}' file
--
:check
是分支标签,用于匹配
/^Z/
的行(因此,从
Z
开始)。
sed
通过循环:

  • p
    打印行(=打印匹配行)
  • 转到
    n
    ext one
  • 将其复制到
    h
    旧缓冲区
  • p
    打印它(=匹配后打印行)
  • e
    x
    更改行,即将
    h
    旧缓冲区移回(=在匹配一行后返回行)
  • b
    ranch to
    check
    如果行与
    ^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