Bash 获取特定数据的流水线
我有一个命令,它给出以下输出:Bash 获取特定数据的流水线,bash,shell,awk,pipelining,Bash,Shell,Awk,Pipelining,我有一个命令,它给出以下输出: #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 有
#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
以及这些部分的b
和c
字段值的部分
样本输出:
#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
有人知道另一种方法吗,或者在cut语句中使用条件句吗?也许
awk
可以在这里帮助您;)试试这个:
mycommand | tr -d " " | awk -F: '/a:/ {a=$2;} /(b:|c:)/ {if (a == "same") print $2;}'
输出:
red
one
blue
two
b:red
c:one
b:blue
c:two
如果您还需要字段名,只需在最后一次打印时将$2
替换为$0
:
mycommand | tr -d " " | awk -F: '/a:/ {a=$2;} /(b:|c:)/ {if (a == "same") print $0;}'
输出:
red
one
blue
two
b:red
c:one
b:blue
c:two
顺便说一下,在运行
awk
version20070501
的macOS 10.12.4上进行了测试 awk
救援
$ 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
$awk-vrs=-F'\n'/a:same/{print$1;
对于(i=2;i我发现,当您的输入中有名称->值对时,最好先创建一个表示该映射的数组,然后只需使用字段名称即可获取字段值,例如:
$ cat tst.awk
BEGIN { RS=""; ORS="\n\n"; 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
$cat tst.awk
开始{RS=”“;ORS=“\n\n”;FS=OFS=“\n”}
{
删除n2v
对于(i=2;i2个一行程序:
GNUgrep
方法:
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
#sec one
a : same
b : red
c : one
#sec two
a : same
b : blue
c : two
使用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
#sec one
a : same
b : red
c : one
#sec two
a : same
b : blue
c : two
工作原理:
/^a:same$/
找到要打印的部分,但它从来不是第一个
行(前面总是有注释行),所以第一个代码
执行的是h
,它覆盖了“hold”中的任何内容
与当前行的缓冲区
- 因此,在下一个循环中,保持缓冲区始终包含上一个循环
行,模式缓冲区包含当前行
- 当
/^a:same$/
为真时,将运行大括号中的代码。它将更改模式并保留缓冲区,p
打印中的内容
保留缓冲区(即注释行)ex
将其更改回,
p
将模式缓冲区(即搜索字符串)打印两倍
获取n
ext行并p
rint它,然后它z
aps
模式缓冲区(将其删除),并打印(即打印一个空行)
我建议用Bash以外的语言进行这种结构化解析。这可能是可行的,但会很痛苦。如果你以前从未使用过Python,那么试试Python,这将是一个有趣的练习。不能同时使用awk吗?是的,使用awk绝对不重要。你想打印b和c部分,因为它们是以字母开头的吗s b和c,还是因为它们在:
右侧非空?