【问题标题】:Difference between two lists using Bash使用 Bash 的两个列表之间的区别
【发布时间】:2012-06-25 06:47:16
【问题描述】:

好的,我的 linux 框中的文本文件中有两个相关列表:

 /tmp/oldList
 /tmp/newList

我需要比较这些列表以查看添加了哪些行以及删除了哪些行。然后,我需要遍历这些行并根据它们是被添加还是删除来执行操作。

如何在 bash 中做到这一点?

【问题讨论】:

标签: bash sorting sed awk grep


【解决方案1】:

diff command 将为您进行比较。

例如,

$ diff /tmp/oldList /tmp/newList

有关更多信息,请参阅上面的手册页链接。这应该解决您问题的第一部分。

【讨论】:

  • 我只是强调diff 命令有大量用于格式化输出的选项,这可以为处理差异的程序提供方便的输入。
  • @chepner 好点.. 绝对值得查看链接的手册页。
【解决方案2】:

我通常使用:

diff /tmp/oldList /tmp/newList | grep -v "Common subdirectories"

grep -v 选项反转匹配:

-v, --invert-match 选定的行是那些不匹配任何指定模式的行 燕鸥。

所以在这种情况下,它采用diff 结果并忽略那些常见的结果。

【讨论】:

    【解决方案3】:

    这是旧的,但为了完整起见,我们应该说,如果你有一个非常大的集合,最快的解决方案是使用 diff 生成一个脚本,然后获取它,如下所示:

    #!/bin/bash
    
    line_added() {
       # code to be run for all lines added
       # $* is the line 
    }
    
    line_removed() {
       # code to be run for all lines removed
       # $* is the line 
    }
    
    line_same() {
       # code to be run for all lines at are the same
       # $* is the line 
    }
    
    cat /tmp/oldList | sort >/tmp/oldList.sorted
    cat /tmp/newList | sort >/tmp/newList.sorted
    
    diff >/tmp/diff_script.sh \
        --new-line-format="line_added %L" \
        --old-line-format="line_removed %L" \
        --unchanged-line-format="line_same %L" \
        /tmp/oldList.sorted /tmp/newList.sorted
    
    source /tmp/diff_script.sh
    

    更改的行将显示为已删除和添加。如果你不喜欢这样,你可以使用--changed-group-format。检查差异手册页。

    【讨论】:

      【解决方案4】:

      如果您的脚本需要可读性,请考虑使用 Ruby。

      仅获取旧文件中的行:

      ruby -e "puts File.readlines('/tmp/oldList') - File.readlines('/tmp/newList')"
      

      仅在新文件中获取行:

      ruby -e "puts File.readlines('/tmp/newList') - File.readlines('/tmp/oldList')"
      

      您可以将其输入到 while 读取循环中以处理每一行:

      while read old ; do
        ...do stuff with $old
      done < ruby -e "puts File.readlines('/tmp/oldList') - File.readlines('/tmp/newList')"
      

      【讨论】:

        【解决方案5】:

        使用comm(1) 命令比较两个文件。它们都需要排序,如果它们很大,您可以事先进行排序,或者您可以使用 bash 进程替换内联进行排序。

        comm 可以采用标志 -1-2-3 的组合,指示要从哪个文件中抑制行(文件 1 独有,文件 2 独有或两者共有)。

        仅获取旧文件中的行:

        comm -23 <(sort /tmp/oldList) <(sort /tmp/newList)
        

        仅在新文件中获取行:

        comm -13 <(sort /tmp/oldList) <(sort /tmp/newList)
        

        您可以将其输入while read 循环以处理每一行:

        while read old ; do
            ...do stuff with $old
        done < <(comm -23 <(sort /tmp/oldList) <(sort /tmp/newList))
        

        对于新行也是如此。

        【讨论】:

          【解决方案6】:

          你试过diff

          $ diff /tmp/oldList /tmp/newList
          
          $ man diff
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-09-06
            • 2014-11-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-08
            相关资源
            最近更新 更多