【问题标题】:How to compare two files on line by line basis regardless of order?无论顺序如何,如何逐行比较两个文件?
【发布时间】:2019-10-01 23:50:54
【问题描述】:

我有两个文件,我想检查该文件中的每一行是否存在。但是,有时每行中第二个单词之后的单词顺序是不同的。没关系,因为我只对前两个单词/列之后的缺失/附加单词感兴趣。

文件_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

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

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

【问题讨论】:

  • @Prune OP 对需求有清晰的描述,一个清晰的例子,一个具体的问题,以及他到目前为止所尝试的内容。他还能做多少才能使它成为一个好问题?
  • 如果文件 A 有 2 行相同的 baz C boo abd 行,而文件 B 只有其中 1 行,输出应该是什么 - 根据您的标准,这些文件是相同还是不同?
  • @EdMorton 他们应该是不同的。 :)
  • 我正在寻找解决指定问题的方法。稻草人示例专门处理整行;要“忽略词序”,必须尝试识别一个词单元。现在这是一个有争议的问题,因为这个问题有一个很好的 shell 答案和一个蛮力的 Python 方法。
  • @Prune 请注意,我在每行的第二个单词之后提到了顺序并不重要(内容只重要),因此不会完全忽略单词顺序。

标签: python shell awk diff ksh


【解决方案1】:

对于“sorted_in”使用 GNU awk:

$ 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 只列出了一次,所以文件应该被报告为不同的。例如:

$ 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 idk 这意味着什么。正如您所看到的,对于给定的示例输入,该工具的行为应如此。你能提供更多细节吗?还要在行尾检查你的文件是否有 control-M,因为它们会搞砸cat -v file
  • 我得到这个作为 awk 脚本的输出 ```` > bar B sm sldkjn ca jd baz C abd boo > foobar A hd ab ac bd
  • 使用的命令:$ awk -f tst.awk file_A file_B。也许我错过了什么
  • 嗯,这意味着您的文件存在差异,它会向您展示这些差异是什么。你运行cat -v file 来检查控制女士了吗?
【解决方案2】:

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()

【讨论】:

    猜你喜欢
    • 2021-12-31
    • 1970-01-01
    • 2015-12-02
    • 2020-06-05
    • 1970-01-01
    • 2014-08-24
    • 2021-09-29
    • 1970-01-01
    相关资源
    最近更新 更多