Linux 基于两列(在两个方向上)删除重复的行,并仅保留一行

Linux 基于两列(在两个方向上)删除重复的行,并仅保留一行,linux,awk,Linux,Awk,我想从制表符分隔的文件中删除重复的行,如下所示: 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.g

我想从制表符分隔的文件中删除重复的行,如下所示:

 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和/或排序有什么方法可以做到这一点吗?

我不是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
declare-A数据库
读行时;做
index=“$(sed's,[[:space:]\+,\n,g”
  • 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:

$ awk '!a[($1<$2?$1:$2),($1<$2?$2:$1)]++' file

如果列中有空格,则应使用
awk-F“\t”
¸

如果这是预期的输出,则示例脚本似乎产生了正确的结果。
awk -F'\t' '!(($0 in x) || ($2 FS $1 in x)); {x[$0]}'
$ 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