如何根据bash中的参数过滤信息

时间:2016-02-23 11:03:03

标签: bash filter

我想以特定方式过滤命令的输出。我们假设以下输出:

==== Foo ====
Line to filter 1
Line to filter 2
Line to filter 3
Line to filter 4
Line to filter 5
==== Bar ====
Line to filter 6
Line to filter 7
Line to filter 8
Line to filter 9
Line to filter 10

我要做的是使用一个命令Lines to filter 1-5进行过滤,具体取决于命令中的“参数”是Foo还是Bar。例如:

command | grep '... Foo ...',输出:

Line to filter 1
Line to filter 2
Line to filter 3
Line to filter 4
Line to filter 5

command | grep '... Bar ...',输出:

Line to filter 6
Line to filter 7
Line to filter 8
Line to filter 9
Line to filter 10

有可能这样做吗?谢谢!

1 个答案:

答案 0 :(得分:1)

你可以做很多这样的方法。使用awk:

awk -v s="Foo" '/^=/&&$2!=s { p=0 } p==1; /^=/&&$2==s { p=1 }' input.txt

这使用标记p,根据找到的任何标题行的内容进行切换。

第二种方法(从我喜欢的123&#39删除的答案中肆无忌惮地被盗)要短得多:

awk -v s="$var" '/^=/{p=$0~s;next} p'

这个awk脚本有两个表达式 - 第一个将p设置为评估$0~s的布尔结果,如果p为真,则第二个打印该行。 p仅更改标题行。我想不出用awk表达这个任务的简短方法。

sed中的方法可能是:

sed -ne '/^==== Foo/,/^====/{;/^====/d;p;}' input.txt

但是你无法将变量传递给sed,所以你要为此重写你的实际脚本,这有点丑陋。如果您想在bash中清理输入,可以使用参数扩展来完成。例如,您可以剥离任何非字母数字字符,如果您非常确定您希望在标题中看到的内容:

s="##Fo@o! "
sed -ne "/^==== ${s//[^[:alnum:]]/}/,/^====/{;/^====/d;p;}" input.txt

当然,sedawk可以从 bash获得,但它们并不代表bash脚本。这也可以单独用bash完成:

s="Foo"; p=false
while read line; do 
  [[ $line =~ ^==== ]] && p=false
  $p && echo "$line"
  [[ $line =~ ^====\ $s ]] && p=true
done < input.txt

这遵循上面awk脚本的示例,设置一个根据我们看到的标题切换的布尔值。