如何忽略 diff 命令中数字负号之间的差异?

如何忽略 diff 命令中数字负号之间的差异?

我有两个主要由矩阵形式的数字组成的大文件,我想使用 diff (或类似的命令)来比较这些文件并确定哪些数字不同。

不幸的是,其中很多数字仅在符号上有所不同,而我对这些差异不感兴趣。我只关心两个数字大小不同的情况。 (即我想要0.523 vs. 0.623,但是不是 0.523 vs. -0.523

是否可以使 diff 忽略符号并仅打印大小不同的数字?

编辑:根据要求的一些输入示例:

文件一:

21   -0.0081318   0.0000000   0.0000000   0.0000000  -0.0138079
22    0.0000000   0.0000000   0.0000000   0.1156119   0.0000000
23    0.0000000   0.0047536   0.0000000   0.0000000   0.0000000

文件2:

21   -0.0081318   0.0000000   0.0000000   0.0000000   0.0032533
22    0.0000000   0.0000000   0.0000000  -0.0250637   0.0000000
23    0.0000000  -0.0047536   0.0000000   0.0000000   0.0000000

假设我的文件的格式大部分是这样的(除了很多很多更长),我想打印出差异,但当它们只是符号时忽略这些差异。例如,我不关心 0.0047536 与 -0.0047536,但我确实想打印 0.1156119 与 -0.0250637。

答案1

鉴于您的 shell 提供了“进程替换”(如最近的bashes),​​请尝试

diff <(tr '-' ' ' <file1) <(tr '-' ' '<file2)
1,2c1,2
< 21    0.0081318   0.0000000   0.0000000   0.0000000   0.0138079
< 22    0.0000000   0.0000000   0.0000000   0.1156119   0.0000000
---
> 21    0.0081318   0.0000000   0.0000000   0.0000000   0.0032533
> 22    0.0000000   0.0000000   0.0000000   0.0250637   0.0000000

答案2

$ xdiff(){ diff -bu <($1 "$2") <($1 "$3"); }
$ xdiff 'sed s/-\([.0-9]\)/\1/g' file1 file2

您可以对数据进行其他标准化。例如,将所有0.01.01-.0100、视为-.01e相同:

$ norm(){ awk '{for(i=1;i<=NF;i++){$i=$i<0?-$i:+$i};print}' "$@"; }
$ xdiff norm file1 file2

答案3

要打印 file2 中的行(其对应的绝对值与 file1 中同一行的对应字段不同),请将 file1 中的行保存在内存中,然后比较它们的绝对值:

function abs(x) {
  return x < 0 ? -x : x;
}

# file 1
NR == FNR {
  file1[$1]=$2" "$3" "$4" "$5" "$6
}

# file 2
NR != FNR {
  split(file1[$1], file1fields);
  if ( abs($2) - abs(file1fields[1]) ||
       abs($3) - abs(file1fields[2]) ||
       abs($4) - abs(file1fields[3]) ||
       abs($5) - abs(file1fields[4]) ||
       abs($6) - abs(file1fields[5]) )
        print;
}

将其保存在文件中,然后运行awk -f /path/to/that/file file1 file2

相关内容