用于比较 2 个文件内容的 AWK 脚本

用于比较 2 个文件内容的 AWK 脚本

我有2个文件..

文件1:

abc|123|check
def|456|map
ijk|789|globe
lmn|101112|equator

文件2:

check
map
equator
globe 

AWK 函数应该将 file1 的第三列(剪切第三列和排序后)与 file2 排序的内容进行比较

  • 如果所有行都匹配,则应返回 1
  • 否则应该返回 2

答案1

function are_all_there {
    local num_diff=$(comm -3 <(cut -d'|' -f3 "$1" | sort) <(sort "$2") | wc -l)
    (( num_diff == 0 )) && return 1 || return 2
}

答案2

根据您的评论,这似乎awk不是您唯一的选择。所以这是一个非 awk 方法。
你没有提到需要独特的问题中的比较,但您uniq在评论中的示例中使用了。如果你不需要独特的匹配,只需删除排序选项即可-u。 (测试于bash)。

(($(comm -3 <( cut -d'|' -f3 file1 | sort -u ) \
            <( sort -u file2 ) | wc -l))) && echo 2 - not all match ||
                                             echo 1 - all match

或者,使用awk进行最终比较 - 在paste​​ .

paste <( cut -d'|' -f3 file1 | sort -u ) \
      <( sort -u file2 ) |
   awk '$1!=$2{m=2; exit} 
     END{ if(m == 2){print "2 - not all match"; exit;} 
                     print "1 - all match";}' 

或者,awk 比较两个输入文件

 awk '{if(NR == FNR){a[NR]=$1}
       else{ if($1 != a[NR]){m=2; exit}}}  
      END{ if(m == 2){print "2 - not all match"; exit;} 
                      print "1 - all match";}' \
    <( cut -d'|' -f3 file1 | sort -u ) \
    <( sort -u file2 ) |

答案3

有趣的CS答案!我们实际上不需要对任何东西进行排序,因为这是纯集比较。

输入文件是一个集合的表示,其中元素是成对的。例如,如果该行在foo中出现 3 次file1,则表示元素 < foo, 3>。如果file2包含foo3次,则意味着两个集合都包含该元素。如果file2不包含foo或包含不同次数的重复foo,则表示不包含 < foo, 3> 的集合。

此外,请注意,像 < , 3> 这样的一组对foo可以用将键映射foo到 3 的哈希来表示。

TXR Lisp awk 宏:

(awk (:begin (set fs "|"))
     (:let (h1 (hash :equal-based)) (h2 (hash :equal-based)))
     ((= arg 1) (inc [h1 [f 2] 0]))
     ((= arg 2) (inc [h2 rec 0]))
     (:end (exit (equal h1 h2))))

如果文件按照所需方式相等,则会产生成功终止状态,否则会产生失败状态:

$ txr comp.tl 文件1 文件2
$回声$?
0
$回显映射>>文件2
$ txr comp.tl 文件1 文件2
$回声$?
1

如果我们想通过解析“1”或“2”输出来使调用程序变得复杂,可以通过更改规则来完成:end

(:end (prn (if (equal h1 h2) "1" "2")))

这是常规 awk 中的情况。主要区别在于我们有简洁的语法,我们不必定义我们引用的任何变量;另一方面,我们必须编写一对循环来比较两个关联数组,并生成我们自己的arg变量来跟踪我们正在处理哪个文件。 (GNU Awk 有用ARGIND于此目的的。)

BEGIN { FS = "|" }
FNR == 1 { arg++ }
arg == 1 { h1[$3]++; }
arg == 2 { h2[$0]++; }
END { same = 1
      for (i in h1)
        if (h1[i] != h2[i]) {
          same = 0
          break
        }
      if (same)
        for (i in h2)
          if (h2[i] != h1[i]) {
            same = 0
            break
          }
      print same ? "1" : "2"; }

相关内容