Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Bash的两个列表之间的差异_Bash_Sorting_Sed_Awk_Grep - Fatal编程技术网

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

使用Bash的两个列表之间的差异,bash,sorting,sed,awk,grep,Bash,Sorting,Sed,Awk,Grep,好的,我的linux框中有两个相关的文本文件列表: /tmp/oldList /tmp/newList 我需要比较这些列表,看看添加了哪些行,删除了哪些行。然后,我需要循环这些行,并根据它们是被添加还是被删除来对它们执行操作 如何在bash中执行此操作?将为您进行比较 e、 g 有关更多信息,请参阅上面的手册页链接。这应该可以解决问题的第一部分。您是否尝试过diff $ diff /tmp/oldList /tmp/newList $ man diff 使用comm(1)命令比较这两个

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

 /tmp/oldList
 /tmp/newList
我需要比较这些列表,看看添加了哪些行,删除了哪些行。然后,我需要循环这些行,并根据它们是被添加还是被删除来对它们执行操作

如何在bash中执行此操作?

将为您进行比较

e、 g


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

您是否尝试过
diff

$ diff /tmp/oldList /tmp/newList

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

comm
可以采用标志
-1
-2
-3
的组合,指示要从哪个文件抑制行(文件1唯一、文件2唯一或两者通用)

要仅获取旧文件中的行,请执行以下操作:

comm -23 <(sort /tmp/oldList) <(sort /tmp/newList)
ruby -e "puts File.readlines('/tmp/oldList') - File.readlines('/tmp/newList')"

新行也是如此。

如果脚本需要可读性,可以考虑使用Ruby

要仅获取旧文件中的行,请执行以下操作:

comm -23 <(sort /tmp/oldList) <(sort /tmp/newList)
ruby -e "puts File.readlines('/tmp/oldList') - File.readlines('/tmp/newList')"
要仅获取新文件中的行,请执行以下操作:

comm -13 <(sort /tmp/oldList) <(sort /tmp/newList)
ruby -e "puts File.readlines('/tmp/newList') - File.readlines('/tmp/oldList')"
您可以将其输入while read循环以处理每一行:

while read old ; do
    ...do stuff with $old
done < <(comm -23 <(sort /tmp/oldList) <(sort /tmp/newList))
while read old ; do
  ...do stuff with $old
done < ruby -e "puts File.readlines('/tmp/oldList') - File.readlines('/tmp/newList')"
读旧时;做
…用$old做一些事情
完成
这是一个老问题,但为了完整起见,我们应该说,如果您有一个非常大的集合,最快的解决方案是使用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组格式。查看差异手册页面。

我通常使用:

diff /tmp/oldList /tmp/newList | grep -v "Common subdirectories"
grep-v
选项将反转匹配:

-v、 --反向匹配 所选行是不匹配任何指定pat的行- 燕鸥


因此,在本例中,它采用了
diff
结果,而忽略了那些常见的结果。

我要强调的是,
diff
命令有大量用于格式化输出的选项,这些选项可以为处理这些差异的程序提供方便的输入。@chepner很好。。这绝对值得查看链接的手册页。同样的问题在4天前被问到