在所需列中查找重复项并在awk中打​​印所选模式?

时间:2013-01-02 17:20:29

标签: linux sed awk

输入文件:Input.txt

A B C
1 rs1 5
1 kp1 5
1 rs2 6
1 ga2 6
1 rs8 9
2 kp3 7
2 rs3 7
2 rs4 5
2 rs5 8
3 kp6 4
3 kp7 6

对于列 A (例如:1,2和3)中的每个类别,分别在 C 列中查找重复项。如果有重复的数字,则在单独的文件中打印每个类别中的非 rs ID列表。

输出文件:

file_category_1.txt

A B C
1 kp1 5
1 ga2 6

file_category_2.txt

A B C
2 kp3 7

file_category_3.txt

A B C

这里file_category_3.txt没有任何输出,因为它没有重复。

4 个答案:

答案 0 :(得分:2)

这将让你大部分时间

awk 'NR==1 {print; next} seen[$1,$3]++ {print}'

答案 1 :(得分:1)

未经测试但应该关闭:

awk '
NR==1 {
   hdr = $0
   next
}
{
   cnt[$1,$3]++
   cats[$1]
   ids[$2]
   map[$1,$3,$2] = $0
}
END {
   for (cat in cats) {
      print hdr > "file_category_" cat ".txt"
   }
   for (key in cnt) {
      if (cnt[key] > 1) {
         split(key,keyA,SUBSEP)
         for (id in ids) {
            if ((key,id) in map) {
               print map[key,id] > "file_category_" keyA[1] ".txt"
            }
         }
      }
   }
}' file

答案 2 :(得分:0)

不太难:这是你可以做的oneliner,用伪代码:

1 2 3中的类别; grep on field $ 1为该类别|只保留$ 3 $ 2(按此顺序)|排序| uniq -c | grep -v“只有1个计数的行”| grep -v“$ 2字段中'rs'的任何出现”> file_category_ $ category.txt

但是,正如Clement指出的那样,你应该完成部分工作^^这就是为什么它只是伪代码(但可以直接用于实际的代码,可能是3mn)

答案 3 :(得分:0)

这里实际上有两个问题,这两个问题都可以使用awk完成。

首先,您需要先将文件拆分为较小的文件:

awk 'NR==1 { r=$0; next } { print ($1==i ? "" : r ORS) $0 > "file_category_" $1 ".txt"; i=$1 }' input.txt

其次,您需要根据您的选择标准过滤较小的文件:

for i in file_category_*.txt; do awk 'FNR==NR { a[$3]++; next } FNR==1 || a[$3]>1 && $2 !~ /^rs/' "$i"{,} > tmp && mv tmp "$i"; done

以下是grep . file_category_*.txt

的结果
file_category_1.txt:A B C
file_category_1.txt:1 kp1 5
file_category_1.txt:1 ga2 6
file_category_2.txt:A B C
file_category_2.txt:2 kp3 7
file_category_3.txt:A B C


或者,如果您有GNU awk并且需要单通道解决方案,则可以使用多维数组执行相同的操作。像:

一样运行
awk -f script.awk input.txt

script.awk的内容:

NR==1 {
    r=$0
    next
}

{
    a[$1][$3][$0]
    next
}

END {
    for (i in a) {
        for (j in a[i]) {
            for (k in a[i][j]) {

                split(k,b)
                print (n==1 ? "" : r ORS) \
                    (length(a[i][j])>1 ?  \
                    (b[2] !~ /^rs/ ? k : "") : "") \
                    > "file_category_" i ".txt"
                n=1
            }
        }
        n=0
    }
}

以下是grep . file_category_*.txt

的结果
file_category_1.txt:A B C
file_category_1.txt:1 kp1 5
file_category_1.txt:1 ga2 6
file_category_2.txt:A B C
file_category_2.txt:2 kp3 7
file_category_3.txt:A B C

或者,这是单行:

awk 'NR==1 { r=$0; next } { a[$1][$3][$0]; next } END { for (i in a) { for (j in a[i]) for (k in a[i][j]) { split(k,b); print (n==1 ? "" : r ORS) (length(a[i][j])>1 ? (b[2] !~ /^rs/ ? k : "") : "") > "file_category_" i ".txt"; n=1 } n=0 } }' input.txt