使用 awk 删除重复的行,使一个更接近另一个文件
Delete repeated rows keeping one closer to another file using awk
我有两个文件
$cat file1.txt
0105 20 20 95 50
0106 20 20 95 50
0110 20 20 88 60
0110 20 20 88 65
0115 20 20 82 70
0115 20 20 82 70
0115 20 20 82 75
如果看到file1.txt,column-1有重复值,分别是0110和0115。
所以我想只根据第 5 列的值保留一行,这些值更接近参考文件中的相应值 (file2.txt)。这里更近的意思是file2.txt中的相等或最接近的值。我不想更改 file1.txt 中的任何值,而只想更改 select 一行。
$cat file2.txt
0105 20 20 95 50
0106 20 20 95 50
0107 20 20 95 52
0110 20 20 88 65 34
0112 20 20 82 80 23
0113 20 20 82 85 32
0114 20 20 82 70 23
0115 20 20 82 72
0118 20 20 87 79
0120 20 20 83 79
因此,如果我们比较两个文件,我们必须保留 0110 20 20 88 65
,因为 file1.txt 中的第 5 列条目(即 65)与参考文件中的条目(即 [= 中的 65)更接近35=]) 并删除其他重复的行。同样,我们必须保留 0115 20 20 82 70
因为 70
更接近 72
并删除以 0115
开头的其他两行
期望输出:
0105 20 20 95 50
0106 20 20 95 50
0110 20 20 88 65
0115 20 20 82 70
我正在尝试使用以下脚本,但没有得到我想要的结果。
awk 'FNR==NR { a[]; next } in a ' file1.txt file2.txt > test.txt
awk '{a[NR]=""} a[NR]!=a[NR-1]{print}' test.txt
我的fortran程序算法是:
# check each entries in column-1 in file1.txt with next rows if they are same or not
i.e. for i=1,i++ do # Here i is ith row
for j=1,j++ do
if a[i,j] != a[i+1,j]; then print the whole row as it is,
else
# find the row b[i,j] in file2.txt starting with a[i,j]
# and compare the 5th column i.e. b[i,j+5] with all a[i,j+5] starting with a[i,j] in file1.txt
# and take the differences to find closest one
e.g. if we have 3 rows starting with same entry, then
we select the a[i,j] in which diff(b[i,j+5],a[i,j+5]) is minumum i=1,2,3
awk 'BEGIN {
while ((getline line < "file2.txt")>0) {
split(line, f);
file2[f[1]] = line;
}
}
{
if (!( in result)) result[] = [=10=];
split(result[], a);
split(file2[], f);
if (abs(f[5]-) < abs(f[5]-a[5])) result[] = [=10=];
}
END {
for (i in result) print result[i];
}
function abs(n) {
return (n < 0 ? -n : n);
}' file1.txt | sort
我有两个文件
$cat file1.txt
0105 20 20 95 50
0106 20 20 95 50
0110 20 20 88 60
0110 20 20 88 65
0115 20 20 82 70
0115 20 20 82 70
0115 20 20 82 75
如果看到file1.txt,column-1有重复值,分别是0110和0115。
所以我想只根据第 5 列的值保留一行,这些值更接近参考文件中的相应值 (file2.txt)。这里更近的意思是file2.txt中的相等或最接近的值。我不想更改 file1.txt 中的任何值,而只想更改 select 一行。
$cat file2.txt
0105 20 20 95 50
0106 20 20 95 50
0107 20 20 95 52
0110 20 20 88 65 34
0112 20 20 82 80 23
0113 20 20 82 85 32
0114 20 20 82 70 23
0115 20 20 82 72
0118 20 20 87 79
0120 20 20 83 79
因此,如果我们比较两个文件,我们必须保留 0110 20 20 88 65
,因为 file1.txt 中的第 5 列条目(即 65)与参考文件中的条目(即 [= 中的 65)更接近35=]) 并删除其他重复的行。同样,我们必须保留 0115 20 20 82 70
因为 70
更接近 72
并删除以 0115
期望输出:
0105 20 20 95 50
0106 20 20 95 50
0110 20 20 88 65
0115 20 20 82 70
我正在尝试使用以下脚本,但没有得到我想要的结果。
awk 'FNR==NR { a[]; next } in a ' file1.txt file2.txt > test.txt
awk '{a[NR]=""} a[NR]!=a[NR-1]{print}' test.txt
我的fortran程序算法是:
# check each entries in column-1 in file1.txt with next rows if they are same or not
i.e. for i=1,i++ do # Here i is ith row
for j=1,j++ do
if a[i,j] != a[i+1,j]; then print the whole row as it is,
else
# find the row b[i,j] in file2.txt starting with a[i,j]
# and compare the 5th column i.e. b[i,j+5] with all a[i,j+5] starting with a[i,j] in file1.txt
# and take the differences to find closest one
e.g. if we have 3 rows starting with same entry, then
we select the a[i,j] in which diff(b[i,j+5],a[i,j+5]) is minumum i=1,2,3
awk 'BEGIN {
while ((getline line < "file2.txt")>0) {
split(line, f);
file2[f[1]] = line;
}
}
{
if (!( in result)) result[] = [=10=];
split(result[], a);
split(file2[], f);
if (abs(f[5]-) < abs(f[5]-a[5])) result[] = [=10=];
}
END {
for (i in result) print result[i];
}
function abs(n) {
return (n < 0 ? -n : n);
}' file1.txt | sort