首页 > 解决方案 > 对特定列上的值进行排序和唯一化

问题描述

我有一个数据分隔:delimited

AA:w_c;w_c;r_c:1;3
BB:sync;sync:4
CC:t_wak;t_wak:6;7;8

我只需要在第 2 列中将一个值打印为唯一值。如果有多个唯一值,则需要在另一个文件中打印。

我试过这个:

#!/bin/bash
sort -u -t : -k2,2 file >> txt
awk -F: '{gsub(";"," ",$3)}1' txt
Output:
BB:sync;sync:4
CC t_wak;t_wak 6 7 8
AA w_c;w_c;r_c 1 3

实际上,我正在尝试对第 2 列中的值进行排序和唯一化,并将该输出复制到另一个名为“txt”的文件中。然后我使用 AWk 替换 ; 第 3 列中的空格似乎上面的代码不起作用。

所需的输出 1:

BB:sync:4
CC:t_wak:6 7 8

以上两个值是我们需要打印的实际输出,因为在第 2 列中它只包含一个值。

下面的需要在另一个文件中打印,因为在第 2 列中它包含多个值。

所需输出 2:

AA:w_c;r_c:1;3  
w_c
r_c

在第 2 列中,它应该只有一个值,如果有多个值,则需要在另一个文件中打印,如上所示。

标签: bashawk

解决方案


这个快速解决方案应该适用于示例:

awk 'BEGIN{FS=OFS=":"} 
{ 
    split($2, a, ";")
    v=""; delete u
    for(i=1;i<=length(a);i++){
    if( ++u[a[i]]<2)
        v=v (i==1?"":";") a[i]
    }
    $2=v
    if(length(u)>1){
        print > "output2.txt"
        next
    }
}7' input

让我们做一个测试:

kent$  awk 'BEGIN{FS=OFS=":"} 
{ 
        split($2, a, ";")
    v=""; delete u
        for(i=1;i<=length(a);i++){
        if( ++u[a[i]]<2)
            v=v (i==1?"":";") a[i]
        }
    $2=v
    if(length(u)>1){
        print > "output2.txt"
        next
    }
}7' f
BB:sync:4
CC:t_wak:6;7;8

kent$  cat output2.txt 
AA:w_c;r_c:1;3

如果您想在 output2.txt 中的 col2 中包含每个值:

awk 'BEGIN{FS=OFS=":";out2="output2.txt"} 
{ 
    split($2, a, ";")
    v=""; delete u
    for(i=1;i<=length(a);i++){
        if( ++u[a[i]]<2)
            v=v (i==1?"":";") a[i]
        }
    $2=v
    if(length(u)>1){
        print > out2
        for(x in u)
            print x > out2
        next
    }
}7' input

然后你会得到:

kent$  cat output2.txt
AA:w_c;r_c:1;3
w_c
r_c

推荐阅读