是否可以使用 bash 在一列中找到具有重复值但在其他列中没有重复值的数据?

Is it possible to find data that have duplicate values in one column but not others using bash?

我有一个包含多列和多行的文件。我想获取数据并找到第 4 列中重复值的行,然后将这些行打印到新文件中。

我的数据文件如下所示:

 RR2.out    -1752.142111    -1099486.696073  0.000000
 SS2.out    -1752.142111    -1099486.696073  0.000000
 RR1.out    -1752.141887    -1099486.555511  0.140562
 SS1.out    -1752.141887    -1099486.555511  0.140562
 RR4.out    -1752.140564    -1099485.725315  0.970758
 SS4.out    -1752.140564    -1099485.725315  0.970758
 RR3.out    -1752.140319    -1099485.571575  1.124498
 SS3.out    -1752.140319    -1099485.571575  1.124498
 SS5.out    -1752.138532    -1099484.450215  2.245858
 RR6.out    -1752.138493    -1099484.425742  2.270331
 SS6.out    -1752.138493    -1099484.425742  2.270331
 file Gibbs kcal rel
 file Gibbs kcal rel

如果我只使用 uniq -d 我只会得到

file Gibbs kcal rel
file Gibbs kcal rel

因为它们是唯一完全匹配的两条线。我想知道的是,是否有一种方法可以找到第 4 列中具有重复值的所有行,而不总是完全匹配。

然后我使用 awk 和 read 读取第 1 列中的文件名,因此理想情况下我不必将数据传输到另一个文件然后再返回,因为我发现这会导致相关错误读取文件名。

在这个例子中,我应该得到以下文件作为输出:

 RR2.out    -1752.142111    -1099486.696073  0.000000
 SS2.out    -1752.142111    -1099486.696073  0.000000
 RR1.out    -1752.141887    -1099486.555511  0.140562
 SS1.out    -1752.141887    -1099486.555511  0.140562
 RR4.out    -1752.140564    -1099485.725315  0.970758
 SS4.out    -1752.140564    -1099485.725315  0.970758
 RR3.out    -1752.140319    -1099485.571575  1.124498
 SS3.out    -1752.140319    -1099485.571575  1.124498
 RR6.out    -1752.138493    -1099484.425742  2.270331
 SS6.out    -1752.138493    -1099484.425742  2.270331
 file Gibbs kcal rel
 file Gibbs kcal rel

这里有一些代码可以完成您正在寻找的内容:

awk ' BEGIN { OLD4 = "No match" }
 == OLD4 { print LAST ; print  } 
{ OLD4 =  ; LAST = [=10=]  }  '  

所以这就是您可能 运行 它的方式:

awk ' BEGIN { OLD4 = "No match" }
 == OLD4 { print LAST ; print  } 
{ OLD4 =  ; LAST = [=11=]  }  '   inputfile

输入文件看起来像这样:

RR2.out    -1752.142111    -1099486.696073  0.000000
 SS2.out    -1752.142111    -1099486.696073  0.000000
 RR1.out    -1752.141887    -1099486.555511  0.140562
 SS1.out    -1752.141887    -1099486.555511  0.140562
 RR4.out    -1752.140564    -1099485.725315  0.970758
 SS4.out    -1752.140564    -1099485.725315  0.970758
 RR3.out    -1752.140319    -1099485.571575  1.124498
 SS3.out    -1752.140319    -1099485.571575  1.124498
 SS5.out    -1752.138532    -1099484.450215  2.245858
 RR6.out    -1752.138493    -1099484.425742  2.270331
 SS6.out    -1752.138493    -1099484.425742  2.270331
 file Gibbs kcal rel
 file Gibbs kcal rel

此程序存在问题,它假设第 4 列已排序。如果确实如此,您可以使用未修改的代码。否则,在将输入传递给 awk 之前按第 4 列对输入进行排序可能是值得的。

要更正排序问题,您可能需要在将文件输入 awk 时对其进行排序。这将改变输出的顺序,因此可能需要更多编码。

这是带有某种输入的 awk 脚本:

awk ' BEGIN { OLD4 = "No match" }
 == OLD4 { print LAST ; print  } 
{ OLD4 =  ; LAST = [=13=]  }  '   <( sort -k4,4 inputfile )

或者:

sort -k4,4 inputfile | awk ' BEGIN { OLD4 = "No match" }
 == OLD4 { print LAST ; print  } 
{ OLD4 =  ; LAST = [=14=]  }  '   

uniq-f/--skip-fields 选项来忽略每行的前 n 个字段。

uniq -D -f3