bash中的选择性差异

时间:2016-03-08 13:40:09

标签: bash diff

我想将两个文件与diff进行比较,但我想跳过一些行。我想跳过的行标记为注释,但仅标记在第一个文件

为了便于复制/粘贴测试,我使用process substitution编写diff命令:

$ diff -y <(echo -e "aaa\nbbb\n#ccc\nddd") <(echo -e "AAAAAA\nbbb\nccc\nddd")
aaa                           | AAAAAA
bbb                             bbb
#ccc                          | ccc
ddd                             ddd
$

可以看出,第一行和第三行都标记为diff(|)。由于#符号,我不希望差异中的第三行。我可以使用-I选项忽略匹配的行,但这要求两个文件都匹配模式。

$ diff -y -I "#.*" <(echo -e "aaa\nbbb\n#ccc\nddd\n#eee") <(echo -e "AAAAAA\nbbb\nccc\nddd\n#EEEE")
aaa                           | AAAAAA
bbb                             bbb
#ccc                          | ccc
ddd                             ddd
#eee                            #EEEE
$ 

有没有办法只根据第一个文件忽略行?

修改 我忘了写我需要echo $?的返回值(diff)来告诉我是否有任何不匹配的行(不包括那些我不想检查的行)。

2 个答案:

答案 0 :(得分:1)

使用wc -l过滤结果,并获得有意义的返回值,您可以使用A=$(diff -y --suppress-common-lines <(echo -e "aaa\nbbb\n#ccc\nddd\neee") <(echo -e "AAAAAA\nbbb\nccc\nddd\n#EEEE") | grep -vE "^#" ); echo "$A"; return $(echo "$A" | wc -l); 来计算非公共线;

aaa                           | AAAAAA
eee                           | #EEEE

输出;

2

返回值;

exit

如果您想直接在脚本中使用此示例而不是在函数中使用return而不是if [ $(echo "$A" | wc -l) -gt 0 ]if [ $? -gt 0 ]而不是static

答案 1 :(得分:1)

根据您的具体要求,您根本不能使用diff。由于您在评论中提到您的文件在行数上匹配,并且您想要成对比较行,您可以这样做:

exec 3<file1 4<file2
while read line1 <&3 && read line2 <&4; do
    if [ "$line1" != "$line2" -a -n "${line1%%#*}" ]; then
        echo "$line1 | $line2"
    fi
done
exec 3<&- 4<&-

我也很确定这适用于任何与POSIX兼容的shell,而不仅仅是bash。