比较Awk中的三个文件

时间:2013-09-10 09:25:35

标签: shell awk gawk

我有三个文件,我想使用awk来比较前两个文件,然后使用与frist文件不匹配的名称更新最后一个文件。

文件1:ignore.txt

bob
diana

文件2:list.txt

alice
bob
chris
diana
elvis

文件3:names.txt

alice
chris
elvis

文件2每隔一段时间就会添加新名称,因此我必须能够将其与其他两个文件进行比较,并将该列表中的任何新名称添加到names.txt。

这是我的脚本到目前为止,比较List和ignore是有效的,但它没有做更新,因为我仍然不明白如何使用getline并将新数组与内存中的文件进行比较。

我正在调用脚本:awk -f compare ignore.txt list.txt并且它可以正常工作。如果我用额外变量调用它,它就不会这样做:awk -f compare -v newnames=1 ignore.txt list.txt

 BEGIN {
  file="list.txt"
  tmpfile="new_list.txt"
  }
# working
FNR == NR { names[$0]++; next }
!names[$0] {
   print > names.txt
}
{ #not working
if (newnames == 1) {
  mvcmd="mv " tmpfile file;
    while ((getline newnames < file) > 0)
      newnames[$0]++; next
     !newnames[$0];
        print > tmpfile 
     system(mvcmd)
     close(dbfile)
  }

我怎样才能让它发挥作用?代码不是很好,因为我觉得它很混乱。遗憾。

3 个答案:

答案 0 :(得分:2)

以下是使用grep

执行此操作的方法
grep -v -f names.txt <(grep -v -f ignore.txt list.txt) >>  names.txt

即使names.txt不存在,这也会有用。 (当然,如果对names.txt进行了新的添加并且再次执行该命令,它将更新list.txt。)

答案 1 :(得分:2)

这是awk

的常见用法
$ awk 'FNR==NR{a[$0];next}!($0 in a)' file1 file2
alice
chris
elvis

只需重写整个file3然后更新它就更容易了:

$ awk 'FNR==NR{a[$0];next}!($0 in a)' file1 file2 > file3

<强>解释

NR是在读取每条记录后递增的awk变量,FNR类似,但每次读取新文件时都会重置为1。 NR==FNR只能在读取第一个文件时为True。在读取第一个文件时,我们创建一个数组a,其中数组中的键是文件中的行,以及存储file1中的所有行,这将删除任何重复项。 next是一个命令,可确保在当前记录上不再执行任何块。读完file1后,我们只需检查数组中是否找到file2中的当前行(即file1)。条件!($0 in a)没有阻止执行,因此默认awk执行{print $0}

你的剧本有很多错误,如果你想学习awk,最好的办法是阅读Effective Awk Programming

答案 2 :(得分:2)

根据您描述问题的方式,这就是您所需要的:

awk 'FILENAME!=ARGV[3]{seen[$0]++;next} !seen[$0]++' file1 file3 file2

使用输出更新file3:

awk 'FILENAME!=ARGV[3]{seen[$0]++;next} !seen[$0]++' file1 file3 file2 >> file3

它甚至会从file2中删除重复的新名称:

$ cat file1
bob
diana

$ cat file2
alice
bill
bob
chris
ted
diana
elvis
ted

$ cat file3
alice
chris
elvis

$ awk 'FILENAME!=ARGV[3]{seen[$0]++;next} !seen[$0]++' file1 file3 file2
bill
ted

如果file3中的所有值也存在于file2中,但可以在file2中重复,那么这就是您所需要的:

awk 'NR==FNR{seen[$0]++;next} !seen[$0]++' file1 file2 > file3

如果file3中的所有值也存在于file2中且无法在file2中重复,则@ sudo_O的解决方案将正常工作。