使用Bash的两个列表之间的差异

时间:2012-06-22 22:56:39

标签: bash sorting sed awk grep

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

 /tmp/oldList
 /tmp/newList

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

我如何在bash中执行此操作?

6 个答案:

答案 0 :(得分:58)

使用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))

和新线类似。

答案 1 :(得分:5)

diff command将为您进行比较。

例如,

$ diff /tmp/oldList /tmp/newList

有关详细信息,请参阅上面的手册页链接。这应该照顾你问题的第一部分。

答案 2 :(得分:3)

如果脚本需要可读性,请考虑使用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')"

答案 3 :(得分:1)

这是旧的,但为了完整起见,我们应该说如果你有一个非常大的集合,最快的解决方案是使用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。检查diff手册页。

答案 4 :(得分:0)

您是否尝试过diff

$ diff /tmp/oldList /tmp/newList

$ man diff

答案 5 :(得分:0)

我通常使用:

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

grep -v选项反转匹配:

  

-v,--invert-match                选定的行是与任何指定的样式都不匹配的行。                燕鸥。

因此,在这种情况下,它将获取diff结果并忽略那些常见的结果。