基于匹配多个值之一的列提取行

时间:2016-01-30 22:25:23

标签: bash awk filter grep col

我有一些包含以下数据的文件:

 160-68 160 68 B-A 0011 3.80247
 160-68 160 68 B-A 0022 3.73454
 160-69 160 69 B-A 0088 2.76641
 160-69 160 69 B-A 0022 3.54446
 160-69 160 69 B-A 0088 4.24609
 160-69 160 69 B-A 0011 3.97644
 160-69 160 69 B-A 0021 1.82292

我需要在第5列的数组中提取具有任何值(可以是负数:ex -12222)的行。

输出[0088,0021]:

160-69 160 69 B-A 0088 2.76641
160-69 160 69 B-A 0088 4.24609
160-69 160 69 B-A 0021 1.82292

我目前正在使用Ruby,但是有没有办法用Bash更快地完成它?

感谢。

3 个答案:

答案 0 :(得分:4)

bash不太可能比ruby更快:bash通常很慢。我会选择awk或perl

awk -v values="0088 0021" '
    BEGIN {
        n = split(values, a)
        for (i=1; i<=n; i++) b[a[i]]=1
    }
    $5 in b
' file
perl -ane 'BEGIN {%v = ("0088"=>1, "0021"=>1)} print if $v{$F[4]}' file

答案 1 :(得分:1)

这是一个基于egrep的解决方案。

假设特殊值数组以简单的CSV字符串形式给出,例如

<div id="original">
  <a href="http://amazon.com/">
    <img src="http://i.imgur.com/GMldHhn.jpg" />
  </a>
</div>
<hr />
<div id="contact">
  <a href="http://amazon.com/">
    <img src="http://i.imgur.com/GMldHhn.jpg" />
  </a>
</div>

然后以下调用egrep将选择所需的行:

A="0088,0021"

在实践中,最好修改上面的正则表达式,使其相对于输入格式不那么脆弱。

如果数组元素($ A)包含egrep特有的字符(例如方括号,圆括号等),则需要注意避免它们。这可以以编程方式完成,例如

egrep "( [^ ]+){3} ($(tr , '|' <<< "$A")) "

另见下面的评论。

答案 2 :(得分:-1)

另一种解决方案

*

其中input.txt是数据文件,您将此脚本称为 ./scriptname 0088 0021