【问题标题】:awk to compare multiple columns in 2 filesawk 比较 2 个文件中的多列
【发布时间】:2023-03-27 12:10:02
【问题描述】:

我想比较 2 个文件中的多个列,而不是打印符合我的条件的行。 这方面的一个例子是:

文件1

apple  green  4
orange  red  5
apple  yellow 6
apple  yellow 8
grape  green 5

文件2

apple  yellow 7
grape  green 10

输出

apple  green  4
orange  red  5
apple  yellow 8

我想删除file1 中的$1$2 对应于file2 中的$1$2 以及当file1 中的$3 小于@ 中的$3 的行987654333@。 我现在只能完成工作的第一部分,即删除来自file1$1$2 对应于$1$2file2 的行(字段由制表符分隔):

awk -F '\t' 'FNR == NR {a[$1FS$2]=$1; next} !($1FS$2 in a)' file2 file1

你能帮我应用最后一个条件吗?

提前非常感谢!

【问题讨论】:

    标签: awk file-comparison


    【解决方案1】:

    你追求的是这个:

    awk '(NR==FNR){a[$1,$2]=$3; next}!(($1,$2) in a) && a[$1,$2] < $3))' <file2> <file1>
    

    【讨论】:

    • 当您在多个位置使用相同的硬编码值集作为键时,请认真考虑使用变量来保存键:'{key=$1 FS $2} (NR==FNR){a[key]=$3; next}!(key in a) &amp;&amp; a[key] &lt; $3))'。如果/当您需要更改密钥时,让生活更轻松,恕我直言,提高清晰度。
    • 它有效,但我必须删除最后两个括号:
    • @Agathe 哪个括号?
    • 它可以工作,但我必须删除最后两个括号:awk '(NR==FNR){a[$1,$2]=$3; next}!(($1,$2) in a) &amp;&amp; a[$1,$2] &lt; $3' &lt;file2&gt; &lt;file1&gt; 另外,我可以要求解释一下代码吗?特别是,我不明白a[key]=$3a[key]&lt;$3 部分。如果我理解正确,您正在创建一个名为 a 的数组,在其中存储文件 2 中的 $1FS$2 (=key),然后在文件 1 中查找 $1FS$2 以不打印它。但是,为什么您似乎在分配数组或将其与列 $3 进行比较?
    • @Agathe a[key] 表示数组a 的元素,索引为key。所以 a[key]=$3 意味着将 $3 的值存储在数组元素 a[key] 中。语句key in a 是检查数组a 是否具有索引为key 的元素的查询
    【解决方案2】:

    在构建数组时存储第三个字段值,然后将其用于比较

    $ awk -F '\t' 'FNR==NR{a[$1FS$2]=$3; next} !(($1FS$2 in a) && $3 > a[$1FS$2])' f2 f1
    apple   green   4
    orange  red 5
    apple   yellow  6
    grape   green   5
    

    最好写成:

    awk -F '\t' '{k = $1FS$2} FNR==NR{a[k]=$3; next} !((k in a) && $3 > a[k])' f2 f1
    

    【讨论】:

    • 不需要字段分隔符,因为awk 默认使用空格(包括制表符)
    • 是的,以防万一将来有人阅读答案的字段由制表符分隔,但字段可以包含空格;)
    猜你喜欢
    • 2019-09-08
    • 2019-05-24
    • 2018-10-23
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    相关资源
    最近更新 更多