我知道与
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
(作为数组中的索引seen
和keep
数组中的值)。
答案2
这是一个两步过程:
用于生成 sed 脚本以删除不需要的行的 awk 脚本
awk 'seen[$0]++ {print NR "d"}' file1 > remove.sed
然后使用 sed 脚本删除所需文件中的行
sed -i -f remove.sed file1 file2