remove the first duplicate line based on a matched field and keep the second matched line
第一次出现,不要删除第二次出现的行。
尝试了以下命令,该命令保留了第一个重复行并删除了其余的重复行。 awk 命令中是否有任何选项可以删除第一个匹配的重复行并保留第二个匹配的行。 awk 以外的命令也可以。输入文件大小可以是 50 GB。我现在正在测试 12 GB 文件。
1 | awk -F'|' '!a[$1]++' |
输入文件内容:
1 2 3 4 5 6 7 8 9 10 11 12 | 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 2 3 4 5 6 7 8 9 10 | 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 提供的以下解决方案
有效地使用
1 | awk -F'|' 'prev && $1 != prev{ print row }{ prev=$1; row=$0 }END{ print row }' file |
"魔术"基于捕获每个当前记录(有效地覆盖它而无需不断累积)并在下一行执行分析。
样本输出:
1 2 3 4 5 6 7 8 9 | 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"} |
第一个解决方案:如果您根本不担心输出中的行顺序,那么就简单地做。
1 | awk 'BEGIN{FS="|"} {a[$1]=$0} END{for(i in a){print a[i]}}' Input_file |
第二个解决方案:如果您担心订单,请使用
1 | awk 'BEGIN{FS="|"} {a[$1]=$0} END{for(i in a){print a[i]}}' Input_file | sort -t'|' -k1 |
第三种解决方案:请您尝试以下方法。如果您担心输出的顺序应该与所示 Input_file.
相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | awk ' BEGIN{ FS="|" } !a[$1]++{ b[++count]=$1 } { c[$1]=$0 } END{ for(i=1;i<=count;i++){ print c[b[i]] } } ' Input_file |
输出如下。
1 2 3 4 5 6 7 8 9 | 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"} |
反转文件并稳定唯一排序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 2 3 4 5 6 7 8 9 | 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"} |
此单行只会从您的文件中删除第一个重复项(第二次出现)。
1 | awk 'a[$1]++ !=1' file |
我们来看一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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 |