Linux Bash脚本中去除多列重复值的最优实现方法
要解决这个问题,核心思路是先把你的基因列表两两分组,然后把每组的两个元素标准化(比如按字母顺序排序),这样不管顺序如何,重复的配对都会变成相同的字符串,最后再去重就可以了。下面给你两种实用的Bash方案,分别对应不同的需求:
方案1:快速去重(不保留原配对的出现顺序)
这个方法最简洁,适合不需要关心原顺序的场景:
# 假设你的输入字符串存在变量里 input="A2M TIAM1 AARSD1 NLRP12 ABCA12 ABCA1 ABCA12 NR1H2 ABCA1 ABCA12 ABCA13 APOA2 ABCA13 CLK1 NLRP12 AARSD1 ABCA13 HAGH ABCC10 ATP2B2" echo "$input" | xargs -n2 | awk '{print ($1 < $2) ? $1" "$2 : $2" "$1}' | sort -u
步骤解析:
xargs -n2:把空格分隔的列表拆成每行两个元素的配对,比如把ABCA12 ABCA1变成单独一行。awk部分:对每行的两个元素按字母顺序排序,这样ABCA12 ABCA1和ABCA1 ABCA12都会变成ABCA1 ABCA12,统一了重复配对的格式。sort -u:去除所有重复的行,最终得到唯一的配对。
方案2:保留首次出现的顺序
如果你希望保留原列表中配对第一次出现的顺序,而不是按字母排序后的顺序,可以用awk来跟踪已出现的配对:
input="A2M TIAM1 AARSD1 NLRP12 ABCA12 ABCA1 ABCA12 NR1H2 ABCA1 ABCA12 ABCA13 APOA2 ABCA13 CLK1 NLRP12 AARSD1 ABCA13 HAGH ABCC10 ATP2B2" echo "$input" | xargs -n2 | awk ' { # 生成标准化的键,用来判断是否重复 key = ($1 < $2) ? $1" "$2 : $2" "$1 # 如果这个键没出现过,就输出原配对并标记为已见过 if (!seen[key]++) print $0 }'
步骤解析:
- 同样先用
xargs -n2拆分配对。 - awk里的
seen数组用来记录已经处理过的标准化配对,只有第一次遇到的配对才会被输出,后续重复的(不管顺序)都会被跳过。 - 输出的是原配对的格式,且顺序和原列表中第一次出现的顺序一致。比如原列表中
AARSD1 NLRP12先出现,后面的NLRP12 AARSD1就会被跳过,最终只保留前者。
内容的提问来源于stack exchange,提问作者Jaume Sastre Tomàs
相关产品推荐
相关产品推荐

