如何逐行比较两个文件而不考虑顺序?

3

我有两个文件,我想检查每个文件中的每一行是否存在。但是,有时每行第二个单词后面的单词顺序可能会不同,这没关系,因为我只对第一个和第二个单词/列之后缺失或额外的单词感兴趣。

文件A:

    foobar A a ab c bd hd
    bar B a c jd sm sldkjn
    baz C boo abd

文件B:

    foobar A a c bd hd ab
    baz C abd boo
    bar B c a jd sm sldkjn

在上面的例子中,那两个文件根据我的标准都是好的。
起初我尝试了
   $ sort -u file_A > outA
   $ sort -u file_B > outB
   $ diff outA outB

这种方式不考虑行顺序。 但是,它会考虑每行中单词的顺序。

我该如何忽略第二列之后每行单词的顺序?


2
@Prune,原帖中已经清晰地描述了需求、给出了明确的示例、提出了具体问题以及列举了自己尝试过的方法。他还需要做些什么才能让这个问题更好呢? - Ed Morton
如果文件A有2行相同的baz C boo abd,而文件B只有其中的1行,根据您的标准,这两个文件应该输出什么结果 - 它们是相同的还是不同的? - Ed Morton
1
@EdMorton 它们应该是不同的。 :) - Mark
我正在寻找解决指定问题的尝试。草稿示例特别处理整行;要“忽略单词顺序”,必须尝试识别单词单位。现在这已经不重要了,因为该问题有一个良好的shell答案和一种蛮力Python方法。 - Prune
@Prune 注意,我提到在每行的第二个单词之后顺序不重要(只有内容很重要),因此单词顺序并非完全被忽略。 - Mark
2个回答

2

使用GNU awk的“sorted_in”:

最初的回答:
$ cat tst.awk
BEGIN { PROCINFO["sorted_in"] = "@val_str_asc" }
{
    key = $1 FS $2
    $1 = $2 = ""
    split($0,f)
    for (i in f) {
        key = key FS f[i]
    }
    keys[key]
}
NR==FNR { a[key]++; next }
{ b[key]++ }
END {
    diff = 0

    for (key in keys) {
        if (a[key] > b[key]) {
            print "<", key
            diff = 1
        }
        else if (b[key] > a[key]) {
            print ">", key
            diff = 1
        }
    }

    exit diff
}

每个键的计数和后续的数字比较是必要的,以识别例如file_A中给定键列出了2次,但file_B仅列出了1次的情况,因此文件应该被报告为不同。例如:

原始答案翻译成“最初的回答”

$ cat file_A
foobar A a ab c bd hd
bar B a c jd sm sldkjn
baz C boo abd
baz C boo abd

$ cat file_B
foobar A a c bd hd ab
baz C abd boo
bar B c a jd sm sldkjn

$ awk -f tst.awk file_A file_B
< baz C abd boo

谢谢你的帮助,但是出于某些原因我仍然不理解它们之间的区别。 - Mark
@Mark 我不知道那是什么意思。正如您所看到的,该工具对于给定的样本输入行为正常。您能提供更多详细信息吗?此外,请检查文件末尾是否有控制字符(control-M),因为这可能会引起问题。可以使用 cat -v file 命令来查看。 - Ed Morton
我得到了这个awk脚本的输出> bar B sm sldkjn c a jd < bar B sm sldkjn a c jd < foobar A bd hd a ab c > baz C abd boo > foobar A hd ab a c bd < baz C boo abd - Mark
命令使用:$ awk -f tst.awk file_A file_B。也许我漏掉了什么东西。 - Mark
那意味着你的文件有差异,并且它正在展示给您这些差异是什么。您运行过 cat -v file 命令以检查控制字符吗? - Ed Morton

1

Python是你的朋友!您可以从以下内容开始:

with open(path1, 'r') as file1:
with open(path2, 'r') as file2:
    for line in file1:
        words = line.split(" ")
        for line in file2:
            for word in words:
                if word not in line:
                    doSomething()
                else:
                    doSomethingElse()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接