如何删除文本文件中的重复行并获取删除的行数?

如何删除文本文件中的重复行并获取删除的行数?

我知道与

awk '!seen[$0]++' filename > output.txt

可以从文本文件中删除所有重复项。但是我如何获得已删除行的列表,以便使用此信息删除另一个文件中的相同行。

我需要这个,因为我想删除用一种语言编写的大型文本文件中的所有重复项,然后删除文件中具有该语言翻译的相同行,而不丢失翻译的匹配。

为了更清楚地说明:(文件1)

line A
line B
line A
line C
...

(文件 2):

line 1
line 2
line 3
line 4
...

从文件 1 中删除“line A”并从文件 2 中删除“line 3”。翻译所需:

line A -> line 1
line B -> line 2
line C -> line 4
... 

文件 1B(已删除重复项)将如下所示:

line A
line B
line C
...

文件 2B(已删除重复项)将如下所示:

line 1
line 2
line 4
... 

答案1

$ awk 'FNR==NR && !seen[$0]++ { keep[FNR]=$0; next } (FNR in keep) { printf("%s -> %s\n", keep[FNR], $0) }' file1 file2
line A -> line 1
line B -> line 2
line C -> line 4

这用程序重现了问题中间的输出awk

程序读取第一个文件 ( file1) 并在第一个块中找到重复的行。该块还保存要保留在数组中的行keep,并按行号索引。

当读取第二个文件(代码中的第二个块)时,如果行号是我们想要保留的行号,则将第一个文件中保存的行与第二个文件中的行一起输出。

保存两个新文件的变体:

awk 'FNR==NR && !seen[$0]++ { keep[FNR]=$0; print >FILENAME ".new"; next } (FNR in keep) { print >FILENAME ".new" }' file1 file2

这将file1.new仅使用 中的唯一行进行写入file1,并且将file2.new使用相同的行进行写入,但来自file2

该解决方案的唯一缺点是它需要 2 个x内存,其中x是第一个文件中唯一行的数量,即它将存储每个唯一行的两个副本file1(作为数组中的索引seenkeep数组中的值)。

答案2

这是一个两步过程:

  1. 用于生成 sed 脚本以删除不需要的行的 awk 脚本

    awk 'seen[$0]++ {print NR "d"}' file1 > remove.sed 
    
  2. 然后使用 sed 脚本删除所需文件中的行

    sed -i -f remove.sed file1 file2
    

相关内容