使用 awk 对两个文件中的列进行排序

使用 awk 对两个文件中的列进行排序

我有两个输入文件

28a39a289906c01159f999a68996091a [email protected]
274d1d2c7e931fb55ac0c91dd41f2be7 [email protected]
44d25d3b1b70b240d5058f1be1cef576 [email protected]
2227a768f6d253b7bf81bb4ecb15b52d [email protected]

28a39a289906c01159f999a68996091a
274d1d2c7e931fb55ac0c91dd41f2be7
44d25d3b1b70b240d5058f1be1cef576
2227a768f6d253b7bf81bb4ecb15b52d

我试图排除文件 1 中文件 2 和文件 1 具有匹配列 1 的所有行。

md5 抑制。

我能找到的是awk 'NR==FNR{a[$1]=$0;next}{print a[$2]}' $1 $2

我知道这非常接近,只是不确定我之前做了什么才能做我现在想做的事情。

答案1

如果顺序并不重要(即排除文件中包含 md5 的所有电子邮件)并且您不喜欢 awk,请使用join:

join -v 1 -j 1 <(sort emails) <(sort excludes)

-v 1告诉它打印第一个文件(电子邮件)中在第二个文件(排除)中没有相应行的行。
-j 1 告诉它只查看每个的第一列。


如果你想使用 awk,我相信这应该可行:

awk 'NF==1{exclude[$1]++} NF==2&&!exclude[$1]' excludes emails

或者,如果两个文件逐行对应,并且您只想排除,例如第 2 行,如果两者在该特定行上具有相同的哈希值,请使用以下命令:

awk 'NF==1{hash[FNR]=$1} NF==2&&hash[FNR]!=$1' excludes emails

答案2

这样做的好处是文件可以按任意顺序排列:

sort file1 file2 | uniq -u --check-chars 32 | grep -E '.{33}'

sort file1 file2正在对文件进行组合和排序,为 uniq 做准备。

uniq -u --check-chars 32仅考虑前 32 个字符,并且使用 时-u,仅打印唯一的行。

grep -E '.{33}'仅打印包含 33 个或更多字符的行。

编辑

正如 Peter.O 指出的那样,这不处理文件列表中的两个或多个条目具有相同 md5 的情况。在这种情况下,这些文件将不会被打印。我join最喜欢这个解决方案。

然而,这个逻辑取决于具有唯一 md5 的所有单独文件,这是一个错误的假设,具体取决于此输出的使用。以下是使用 md5sum 逻辑的备份脚本示例。虽然join逻辑正确地识别了 fileA 和 fileB (与我的解决方案不同),但仍然存在一个问题:

echo "hello world" > fileA
cp fileA fileB
./backup_script.sh
cp fileA fileC
./backup_script.sh

该操作是否需要备份 fileC?

答案3

这个命令应该有效:

awk '
  NR==FNR {
    a[$1]=$0;
    next
  }
  { if ( a[$1] ) delete a[$1] } 
  END { 
    for ( md5 in a ) { 
      if ( a[md5] ) { print a[md5] } 
    } 
  }
' file1 file2

相关内容