Unix 根据匹配字段删除第一个重复行,并保留第二个匹配行 输入文件有3个字段。每个字段由一个|(管道)分隔 第一个字段是键字段,已排序。第一个字段中的每个键可能出现一次或两次 如果同一密钥在第一个字段中存在两次,则删除 第一个引用,不要删除第二个引用的行 如果某个键只出现一次,则不要删除该行 第三个字段中的输入数据在整个文件中都是唯一的

Unix 根据匹配字段删除第一个重复行,并保留第二个匹配行 输入文件有3个字段。每个字段由一个|(管道)分隔 第一个字段是键字段,已排序。第一个字段中的每个键可能出现一次或两次 如果同一密钥在第一个字段中存在两次,则删除 第一个引用,不要删除第二个引用的行 如果某个键只出现一次,则不要删除该行 第三个字段中的输入数据在整个文件中都是唯一的,unix,awk,duplicates,match,Unix,Awk,Duplicates,Match,尝试了下面的命令,该命令保留第一个重复行并删除其余重复行。awk命令中是否有任何选项可以删除第一个匹配的重复行并保留第二个匹配行。awk以外的命令也可以。输入文件大小可以是50 GB。我现在正在测试12GB的文件 awk -F'|' '!a[$1]++' 输入文件内容: 1|xxx|{name: "xyz"} 2|xxx|{name: "abcfgs"} 3|xxx|{name: "egg"} 4|xxx|{name: "eggrgg"} 5|xxx|{name: "xsdsyzsgngn"}

尝试了下面的命令,该命令保留第一个重复行并删除其余重复行。awk命令中是否有任何选项可以删除第一个匹配的重复行并保留第二个匹配行。awk以外的命令也可以。输入文件大小可以是50 GB。我现在正在测试12GB的文件

awk -F'|' '!a[$1]++'
输入文件内容:

1|xxx|{name: "xyz"}
2|xxx|{name: "abcfgs"}
3|xxx|{name: "egg"}
4|xxx|{name: "eggrgg"}
5|xxx|{name: "xsdsyzsgngn"}
5|xxx|{name: "gbgnfxyz"}
6|xxx|{name: "xyz"}
7|xxx|{name: "xynfnfnnnz"}
7|xxx|{name: "bvbv"}
8|xxx|{name: "xyz"}
9|xxx|{name: "xyz"}
....
处理输入文件后预期的输出:

1|xxx|{name: "xyz"}
2|xxx|{name: "abcfgs"}
3|xxx|{name: "egg"}
4|xxx|{name: "eggrgg"}
5|xxx|{name: "gbgnfxyz"}
6|xxx|{name: "xyz"}
7|xxx|{name: "bvbv"}
8|xxx|{name: "xyz"}
9|xxx|{name: "xyz"}
....
编辑

分别尝试了以下由@RavinderSingh13@RomanPerekhrest提供的解决方案

对于12GB输入文件,以下解决方案在第一次运行时耗时1分20秒,在第二次运行时耗时1分46秒:

awk '
BEGIN{
  FS="|"
}
!a[$1]++{
  b[++count]=$1
}
{
  c[$1]=$0
}
END{
  for(i=1;i<=count;i++){
    print c[b[i]]
  }
}
' Inputfile  > testawk.txt

这两种解决方案都如预期的那样起作用。我将在再做几次性能测试后使用上述任何一项。

此一行将仅从您的文件中删除第一个副本(第二个副本)

awk 'a[$1]++ !=1' file
让我们看一个例子:

kent$  cat f
1
2
3
2 <- should be removed
4
3 <- should be removed
5
6
7
8
9
2 <- should be kept
3 <- should be kept
10

kent$  awk 'a[$1]++ !=1' f
1
2
3
4
5
6
7
8
9
2
3
10
kent$f类
1.
2.
3.
2第一种解决方案:若您根本不担心输出中行的顺序,那个么只需简单地执行即可

awk 'BEGIN{FS="|"} {a[$1]=$0} END{for(i in a){print a[i]}}' Input_file


第二个解决方案:添加一个带有
awk
更少数组和
sort
的解决方案,以防您担心订单

awk 'BEGIN{FS="|"} {a[$1]=$0} END{for(i in a){print a[i]}}' Input_file | sort -t'|' -k1


第三种解决方案:请尝试以下方法。若您担心输出的顺序,那个么输出的顺序应该和显示的输入文件相同

awk '
BEGIN{
  FS="|"
}
!a[$1]++{
  b[++count]=$1
}
{
  c[$1]=$0
}
END{
  for(i=1;i<=count;i++){
    print c[b[i]]
  }
}
'  Input_file

使用awk高效地表达:

awk -F'|' 'prev && $1 != prev{ print row }{ prev=$1; row=$0 }END{ print row }' file
“魔法”基于捕获每个当前记录(有效地覆盖它而无需不断累积)并对下一行执行分析

样本输出:

1|xxx|{name: "xyz"}
2|xxx|{name: "abcfgs"}
3|xxx|{name: "egg"}
4|xxx|{name: "eggrgg"}
5|xxx|{name: "gbgnfxyz"}
6|xxx|{name: "xyz"}
7|xxx|{name: "bvbv"}
8|xxx|{name: "xyz"}
9|xxx|{name: "xyz"}

反转文件并进行唯一排序:

cat <<EOF |
1|xxx|{name: "xyz"}
2|xxx|{name: "abcfgs"}
3|xxx|{name: "egg"}
4|xxx|{name: "eggrgg"}
5|xxx|{name: "xsdsyzsgngn"}
5|xxx|{name: "gbgnfxyz"}
6|xxx|{name: "xyz"}
7|xxx|{name: "xynfnfnnnz"}
7|xxx|{name: "bvbv"}
8|xxx|{name: "xyz"}
9|xxx|{name: "xyz"}
EOF
tac | sort -s -t'|' -k1,1 -u

tac
是一个GNU实用程序。由于您的文件很大,请将文件名传递给
tac
,这样它就可以从后面读取文件,并使用
-T,--temporary directory=DIR
选项和
sort
对如此大的文件进行排序(如果您有足够的ram,也可以不排序)。

我没有看到从预期输出中删除任何重复的文件。“请详细说明。”詹姆斯布朗说。钥匙是
$1
第三、第四。。。他们应该像第一次一样被移除吗?在没有重复的情况下,您还需要查看第一个实例吗?在您的示例中,前缀“5 | xxx |”是指输入文件xxx的第5行吗?或者它是输入的一部分?为什么预期的输出包括第1行的“xyz”-是否应该因为第6行的“xyz”而将其删除?对我来说,第一个匹配项应该删除,第二个匹配项应该出现。@在零中,所以您只想有重复的数据?例如,
5
在我的示例中,没有DUP,是否应该保留它?请给出一个更好的输入/输出示例。我完全搞糊涂了。@inzero如果您有10行具有相同的键,您想在输出中有第2-10行吗?只有1或2行具有相同的键。请记住,OP说文件是50G。如果我正确理解代码,
c[]
存储整个文件。@Kent,是的,是真的,让我把2倍输入文件读取概念也放进去,但不确定这是否会比这个更快。@Kent,你好,先生,我的第二个解决方案怎么样?先生,我相信这应该比我上一次的更快,这不是更快或更慢。我不知道如果OP的系统坏了会发生什么
1|xxx|{name: "xyz"}
2|xxx|{name: "abcfgs"}
3|xxx|{name: "egg"}
4|xxx|{name: "eggrgg"}
5|xxx|{name: "gbgnfxyz"}
6|xxx|{name: "xyz"}
7|xxx|{name: "bvbv"}
8|xxx|{name: "xyz"}
9|xxx|{name: "xyz"}
cat <<EOF |
1|xxx|{name: "xyz"}
2|xxx|{name: "abcfgs"}
3|xxx|{name: "egg"}
4|xxx|{name: "eggrgg"}
5|xxx|{name: "xsdsyzsgngn"}
5|xxx|{name: "gbgnfxyz"}
6|xxx|{name: "xyz"}
7|xxx|{name: "xynfnfnnnz"}
7|xxx|{name: "bvbv"}
8|xxx|{name: "xyz"}
9|xxx|{name: "xyz"}
EOF
tac | sort -s -t'|' -k1,1 -u
1|xxx|{name: "xyz"}
2|xxx|{name: "abcfgs"}
3|xxx|{name: "egg"}
4|xxx|{name: "eggrgg"}
5|xxx|{name: "gbgnfxyz"}
6|xxx|{name: "xyz"}
7|xxx|{name: "bvbv"}
8|xxx|{name: "xyz"}
9|xxx|{name: "xyz"}