我有这样一个文件:
bar 1
foo 1
how now
manchu 50
foo 2
brown cow
manchu 55
foo 3
the quick brown
manchu 1
bar 2
foo 1
fox jumped
manchu 8
foo 2
over the
manchu 20
foo 3
lazy dog
manchu 100
foo 4
manchu 5
foo 5
manchu 7
bar 3
bar 4
Run Code Online (Sandbox Code Playgroud)
我想搜索'manchu 55'并收到:
FOONUMBER = 2
(上面'manchu 55'的foo#)
BARNUMBER = 1
(上面的那个酒吧#foo)
PHRASETEXT ="棕色牛"
('满洲55'上方的文字)
所以我最终可以输出:
棕色的牛,酒吧1,foo 2.
到目前为止,我已经完成了一些非常丑陋的grep代码,如:
FOONUMBER=`grep -e "manchu 55" -e ^" foo" -e ^"bar" | grep -B 1 "manchu 55" | grep "foo" | awk '{print $2}'`
BARNUMBER=`grep -e ^" foo $FOONUMBER" -e ^"bar" | grep -B 1 "foo $FOONUMBER" | grep "bar" | awk '{print $2}'`
PHRASETEXT=`grep -B 1 "manchu 55" | grep -v "manchu 55"`
Run Code Online (Sandbox Code Playgroud)
这段代码有3个问题:
我怀疑我可以用sed这样做,做类似的事情:
FOONUMBER=`sed -n '/foo/,/manchu 55/p' | grep foo | awk '{print $2}'
Run Code Online (Sandbox Code Playgroud)
不幸的是,sed太贪心了.我一直在阅读AWK和状态机,这似乎是一个更好的方法来做到这一点,但我仍然不能很好地理解它设置它.
正如你现在可能已经确定的那样,编程不是我为生活所做的,但最终我已经把这个推向了我.我希望能够重写我已经拥有的更高效,并且希望不会太复杂,因为没有编程学位的其他一些可怜的草皮可能最终将不得不支持在未来某个日期对它进行的任何更改.
用awk:
awk -v nManchu=55 -v OFS=", " '
$1 == "bar" {bar = $0} # store the most recently seen "bar" line
$1 == "foo" {foo = $0} # store the most recently seen "foo" line
$1 == "manchu" && $2 == nManchu {print prev, bar, foo}
{prev = $0} # remember the previous line
' file
Run Code Online (Sandbox Code Playgroud)
输出
brown cow, bar 1, foo 2
Run Code Online (Sandbox Code Playgroud)
使用"nManchu = 100"输出运行
lazy dog, bar 2, foo 3
Run Code Online (Sandbox Code Playgroud)
这样做的好处是只需要通过文件一次,而不是解析文件3次,得到"bar","foo"和prev行.