我有一个这样的文件:
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
我想搜索 'manchu 55' 并收到:
('manchu 55' 上面的 foo #)
(那个 foo 上方的栏 #)
('满族55'上方一行的文字)
所以我最终可以输出:
到目前为止,我已经用一些非常难看的 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"`
这段代码有3个问题:
我怀疑我可以用 sed 做到这一点,做类似的事情:
FOONUMBER=`sed -n '/foo/,/manchu 55/p' | grep foo | awk '{print $2}'
不幸的是 sed 太贪婪了。我一直在阅读 AWK 和状态机,这似乎是一种更好的方法,但我仍然不太了解它以进行设置。
正如您现在可能已经确定的那样,编程不是我的谋生之道,但最终我受到了这种压力。我希望重写我已经拥有的内容,以提高效率,希望不会太复杂,因为其他一些没有编程学位的糟糕草皮可能最终不得不在 future 的某个日期支持对它的任何更改。
最佳答案
使用 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
产出
brown cow, bar 1, foo 2
使用“nManchu=100”输出运行
lazy dog, bar 2, foo 3
这样做的好处是只通过一次文件,而不是解析文件 3 次来获得 "bar"、"foo"和 prev 行。