将列与多个可能的值匹配

时间:2018-10-29 04:26:05

标签: shell unix awk

我正在尝试使用awk来过滤文件中的数据。到目前为止,对于单个值,我正在使用以下命令

hadoop fs -text file:///a/b/filename.snappy  awk -F'|'  '$11 == 655' > filter_20180705.txt

我想传递比较部分的值列表,而不是传递$11 == 655 IN(列表)之类的列表。任何对此的想法都会有所帮助

样本数据:

$11

到目前为止,我得到的结果是

karthick,bangalore,software,it,bfsi,spark,hadoop,bigdata,etl,pentaho,655,dev
kumar,bangalore,software,it,bfsi,spark,hadoop,bigdata,etl,pentaho,611,dev
Raj,bangalore,software,it,bfsi,spark,hadoop,bigdata,etl,pentaho,800,dev
John,bangalore,software,it,bfsi,spark,hadoop,bigdata,etl,pentaho,823,dev

我需要在比较过滤器中传递一个列表。例如,我要添加karthick,bangalore,software,it,bfsi,spark,hadoop,bigdata,etl,pentaho,655,dev 611。因此预期结果将是

823

2 个答案:

答案 0 :(得分:2)

Awk的上下文中定义一个变量(使用-v)以包括您的正则表达式匹配项(由|分隔)并按以下方式进行匹配。 ~Awk中的正则表达式匹配运算符,可让您将$11与定义的字符串匹配(请参阅How to Use Regular Expressions)。

awk -F, -v list="655|611|823" '$11 ~ list' file

使用上述方法,您的命令将转换为将$11与变量list中定义的任何条目进行匹配。要否定您的正则表达式匹配项(即与我要匹配的项相反),请使用否定!运算符为

awk -F, -v list="655|611|823" '$11 !~ list' file

为避免像1182345这样的错误匹配成为匹配的一部分,请通过添加开始和结束模式来使正则表达式更加严格

awk -F, -v list="655|611|823" 'BEGIN{list="^(" list ")$"} $11 ~ list' file

答案 1 :(得分:0)

为了提高效率,我将按照以下步骤进行操作:

awk -F, -v list='655,611,823' '
    BEGIN {
        split(list,tmp)
        for (i in tmp) {
            expected[tmp[i]]
        }
    }
    $11 in expected
' file

那样,您只需对每个输入行进行哈希查找,而不是进行正则表达式比较。