管道以获取某些数据



我有一个命令,可以给出以下输出:

#sec one
a : same
b : red
c : one
d :
e :
f :
#sec two
a : same
b : blue
c : two
d :
e :
#sec three
a : different
b : green
c : three
d :
e :
#sec four
a : different
b : yellow
c : four
#sec five
a : different
b : pink
c : five

有很多这样的部分。我只需要具有a : same的部分以及这些部分的bc字段的值。

样本输出:

#sec one
a : same
b : red
c : one

#sec two
a : same
b : blue
c : two

这就是我到目前为止所做的!tr -s使其相同间隔。

mycommand | tr -s " " | cut -d ':' -f 2

有人知道另一种方法或在剪切语句中使用条件吗?

也许awk可以在这里为您提供帮助;(尝试以下操作:

mycommand | tr -d " " | awk -F: '/a:/ {a=$2;} /(b:|c:)/ {if (a == "same") print $2;}'

输出:

red
one
blue
two

如果您还需要字段名称,只需在上一个print中将$2替换为$0

mycommand | tr -d " " | awk -F: '/a:/ {a=$2;} /(b:|c:)/ {if (a == "same") print $0;}'

输出:

b:red
c:one
b:blue
c:two

顺便说一句,在 macos 10.12.4 上测试了awk版本20070501

awk to Rescue!

$ awk -v RS= -F'n' '/a : same/{print $1; 
                                for(i=2;i<=NF;i++) if($i~/^(a|b|c)/) print $i; 
                                print ""}' file    
#sec one                                                                                                                                  
a : same                                                                                                                                  
b : red                                                                                                                                   
c : one                                                                                                                                   
#sec two                                                                                                                                  
a : same                                                                                                                                  
b : blue                                                                                                                                  
c : two       

我在输入中有名称 ->值对时发现,最好首先创建一个代表映射的数组,然后您可以通过使用其名称,例如。:

$ cat tst.awk
BEGIN { RS=""; ORS="nn"; FS=OFS="n" }
{
    delete n2v
    for (i=2;i<=NF;i++) {
        name = value = $i
        sub(/[[:space:]]*:.*/,"",name)
        sub(/^[^:]+:[[:space:]]*/,"",value)
        n2v[name] = value
    }
}
n2v["a"] == "same" { print $1, p("a"), p("b"), p("c") }
function p(n) { return (n " : " n2v[n]) }
$ awk -f tst.awk file
#sec one
a : same
b : red
c : one
#sec two
a : same
b : blue
c : two

这样,您就可以通过只需调整脚本的最后2行而以任何想要的顺序来琐碎,鲁棒地修改脚本以打印所需的任何字段。

两个单线:

  1. gnu grep方法:

    grep --group-separator= -B1 -A2 '^a : same$' input_file
    

    输出:

    #sec one
    a : same
    b : red
    c : one
    #sec two
    a : same
    b : blue
    c : two
    
  2. sed的小缓冲区:

    sed -n '/^a : same$/{x;p;x;p;n;p;n;p;z;p};h' input_file
    

    输出:

    #sec one
    a : same
    b : red
    c : one
    #sec two
    a : same
    b : blue
    c : two
    

    如何工作:

    • /^a : same$/找到要打印的部分,但这绝不是第一个线,(总是有前面的评论行(,因此第一个代码执行的是h,它覆盖了" hold "中的任何内容带有当前线的缓冲区。

    • 因此,下一个周期, hold 缓冲区始终包含以前的 线,模式缓冲区包含当前行。

    • /^a : same$/为True时,运行Curly Bracs中的代码。它e x更改模式 hold buffer, p rints
      中的内容 hold buffer,(评论行(,e x将它们更改为 p rints 模式 buffer,(,即搜索字符串(,两次获取n Ext Line并将p RINT进行,之后 z aps aps模式 buffer,(删除它(和 p rint( i。

相关内容

  • 没有找到相关文章

最新更新