37

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

 /tmp/oldList
 /tmp/newList

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

我如何在 bash 中做到这一点?

4

6 回答 6

82

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

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

对于新线路也是如此。

于 2012-06-23T00:08:40.153 回答
8

diff 命令将为您进行比较。

例如,

$ diff /tmp/oldList /tmp/newList

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

于 2012-06-22T22:58:51.827 回答
5

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

要仅在旧文件中获取行:

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

要仅在新文件中获取行:

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

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

while read old ; do
  ...do stuff with $old
done < ruby -e "puts File.readlines('/tmp/oldList') - File.readlines('/tmp/newList')"
于 2013-11-07T00:10:09.340 回答
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。检查差异手册页。

于 2015-02-03T19:57:39.650 回答
1

我通常使用:

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

grep -v选项反转匹配:

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

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

于 2019-01-26T11:35:40.477 回答
0

你有没有尝试过diff

$ diff /tmp/oldList /tmp/newList

$ man diff
于 2012-06-22T22:58:52.827 回答