我想从制表符分隔的文件中删除重复的行,如下所示:
arahy.Tifrunner.gnm1.ann1.A4HWYP arahy.Tifrunner.gnm1.ann1.BWH72M
arahy.Tifrunner.gnm1.ann1.A4HWYP arahy.Tifrunner.gnm1.ann1.PK5V4W
arahy.Tifrunner.gnm1.ann1.BWH72M arahy.Tifrunner.gnm1.ann1.A4HWYP
arahy.Tifrunner.gnm1.ann1.D7QF3J arahy.Tifrunner.gnm1.ann1.A6ZB5M
arahy.Tifrunner.gnm1.ann1.A6ZB5M arahy.Tifrunner.gnm1.ann1.D7QF3J
基于第1列和第2列获取具有一个方向行的输出文件,如下所示:
arahy.Tifrunner.gnm1.ann1.A4HWYP arahy.Tifrunner.gnm1.ann1.BWH72M
arahy.Tifrunner.gnm1.ann1.A4HWYP arahy.Tifrunner.gnm1.ann1.PK5V4W
arahy.Tifrunner.gnm1.ann1.D7QF3J arahy.Tifrunner.gnm1.ann1.A6ZB5M
我正在尝试代码
awk -F'\t' '!x[$2];{x[$1]++}' input.txt > out.txt
但是它没有提供所需的输出,而是仅仅删除了原始文件的最后一行。 有什么办法可以使用awk和/或sort?
答案 0 :(得分:4)
$ awk 'BEGIN{FS=OFS="\t"}
!(($1 FS $2 in x) || ($2 FS $1 in x));
{x[$1 FS $2]}' ip.txt
arahy.Tifrunner.gnm1.ann1.A4HWYP arahy.Tifrunner.gnm1.ann1.BWH72M
arahy.Tifrunner.gnm1.ann1.A4HWYP arahy.Tifrunner.gnm1.ann1.PK5V4W
arahy.Tifrunner.gnm1.ann1.D7QF3J arahy.Tifrunner.gnm1.ann1.A6ZB5M
BEGIN{FS=OFS="\t"}
将输入和输出字段分隔符设置为制表符{x[$1 FS $2]}
使用由制表符分隔的第一和第二字段作为键$1 FS $2 in x
和$2 FS $1 in x
检查第一和第二字段是否以任何顺序作为键存在您还可以将其简化为:
awk 'BEGIN{FS=OFS="\t"} !(($0 in x) || ($2 FS $1 in x)); {x[$0]}'
或(只是意识到不需要OFS)
awk -F'\t' '!(($0 in x) || ($2 FS $1 in x)); {x[$0]}'
答案 1 :(得分:2)
另一个awk:
$ awk '!a[($1<$2?$1:$2),($1<$2?$2:$1)]++' file
输出:
arahy.Tifrunner.gnm1.ann1.A4HWYP arahy.Tifrunner.gnm1.ann1.BWH72M
arahy.Tifrunner.gnm1.ann1.A4HWYP arahy.Tifrunner.gnm1.ann1.PK5V4W
arahy.Tifrunner.gnm1.ann1.D7QF3J arahy.Tifrunner.gnm1.ann1.A6ZB5M
如果列中有空格,则应使用awk -F"\t"
¸
答案 2 :(得分:0)
我不是awk专家,因此,如果您有兴趣,可以使用Bash解决方案:
declare -A db
while read line; do
index="$(sed 's,[[:space:]]\+,\n,g' <<<"$line" | sort)"
[ -z "${db[$index]}" ] && echo "$line"
db[$index]=1
done < input.txt > out.txt
这里的窍门是创建一个不关心记录中值顺序的索引,我可以通过使用sed
将每个记录转换为一组行,然后运行它来完成此操作。 sort
。理想情况下,sort
允许我们对“单词”进行排序,但AFAIK不允许。