Bash 如果第2列字段有多个值,则格式化输出

Bash 如果第2列字段有多个值,则格式化输出,bash,awk,ruby,Bash,Awk,Ruby,我的数据如下所示: Joe:23;23;56:zz Jim:44;44:cz Rob:45;98:fc 在第2列中,如果有多个值,则需要单独打印。 应删除重复项,并且仅打印唯一值 我尝试了以下方法来删除重复项: sort -u -t : -k 2,2 file_name Output: Joe:23;23;56:zz Jim:44;44:cz Rob:45;98:fc 期望输出: Jim:44:cz Below ones need to print separately because

我的数据如下所示:

Joe:23;23;56:zz
Jim:44;44:cz
Rob:45;98:fc
在第2列中,如果有多个值,则需要单独打印。 应删除重复项,并且仅打印唯一值

我尝试了以下方法来删除重复项:

sort -u -t : -k 2,2 file_name 
Output:
Joe:23;23;56:zz
Jim:44;44:cz
Rob:45;98:fc
期望输出:

Jim:44:cz

Below ones need to print separately because column 2 has more than one value or we can append this output to other file.txt 
Joe:23;56:zz
Rob:45;98:fc

你能试试下面的吗。这将创建两个输出文件,其中一个文件的第2列中有两个值的行,另一个输出文件的第2列中有两个以外的值。输出文件名将为
out\u file\u two\u cols
out\u file\u more\u two\u cols
,您可以根据需要进行更改

awk '
BEGIN{
  FS=OFS=":"
}
{
  delete a
  val=""
  num=split($2,array,";")
  for(j=1;j<=num;j++){
    if(!a[array[j]]++){
       val=(val?val ";":"")array[j]
    }
  }
  $2=val
  num=split($2,array,";")
}
num==1{
  print > ("out_file_two_cols")
  next
}
{
  print > ("out_file_more_than_two_cols")
}
' Input_file
awk'
开始{
FS=OFS=“:”
}
{
删除
val=“”
num=拆分($2,数组“;”)
对于(j=1;j(“out\u file\u two\u cols”)
下一个
}
{
打印>(“输出文件多于两列”)
}
'输入文件
说明:在这里为BEGIN部分中输入文件的所有行设置字段分隔符和输出字段分隔符:。然后在main部分中删除名为a的数组并将变量val置零,后面部分将进一步说明并由程序使用,删除它们以避免获取i的冲突r此处为以前的值

将第二个字段拆分为数组,方法是将分隔符设置为
,并在此处获取num变量中的元素总数。现在运行for循环,从1到num值,遍历第二个字段的所有元素

如果数组a中不存在所有元素的第二个字段的当前值,则检查条件,然后将其添加到变量val中,并继续对第二个字段的所有元素执行此操作

然后将val的值赋给第二列。现在再次检查通过拆分新的第二列中有多少元素,num将告诉我们相同的结果

如果num为1,则检查条件意味着当前/编辑的第二个字段只有1个元素,然后将其打印到一个字段输出文件中,否则将其打印到其他输出文件中。

这里有一个小脚本

!/usr/bin/env ruby
输入=File.new“文件名”
single=File.new“一个值”,“w”
multiple=File.new“两个值”,“w”
输入每个do |行|
字段=行。拆分“:”
值=字段[1]。拆分(“;”).uniq.sort
字段[1]=value.join“
new_line=fields.join:“
如果value.size==1

单个另一个
awk

$ awk 'function join() {
         s=sep="";
         for(k in b) {s=s sep k; sep=";"}
         return s}

         BEGIN {FS=OFS=":"}
               {n=split($2,a,";");
                delete b;
                for(i=1;i<=n;i++) b[a[i]]
                $2=join()
                if(length(b)==1) print;
                else {multi=multi ORS $0}}

          END  {print "\nmultiple values:" multi}' file

Jim:44:cz

multiple values:
Joe:23;56:zz
Rob:45;98:fc
$awk'函数联接(){
s=sep=“”;
对于(k in b){s=s sep k;sep=“;”}
返回s}
开始{FS=OFS=“:”}
{n=拆分($2,a,“;”);
删除b;
对于(i=1;i源数据:

$ cat colon.dat
Joe:23;23;56:zz
Jim:44;44:cz
Rob:45;98:fc
一个
awk
解决方案:

awk -F":" '                                        # input field separator is colon
BEGIN   { OFS=FS }                                 # output field separate or colon

        { n=split($2,arr,";")                      # split field 2 by semi-colon
          m=n                                      # copy our array count
          delete seen                              # reset seen array
          for ( i=1 ; i<=n ; i++ ) {               # loop through array indices
            if ( arr[i] in seen ) {                # if entry has been seen then ...
                delete arr[i]                      #     remove from array and ....
                m--                                #     decrement our total count
            }
            else {            
                seen[arr[i]]                       # otherwise add element to the seen arrray
            }
          }

          outf="single.out"                        # output file for single entries

          if ( m >= 2 ) {
                outf="multiple.out"                # output file for multiple entries
          }

          printf "%s%s", $1, OFS > outf            # print header

          sep=""                                   # separator for first field is empty string

          for ( i in arr ) {                       # print remaining array elements
                printf "%s%s", sep, arr[i] > outf
                sep=";"                            # set separator to semi-colon for fields 2+
          }

          printf "%s%s\n", OFS, $3 > outf          # print trailer
        }
' colon.dat

对于第二组,您所说的“单独打印”
是什么意思?您是否希望将其打印为显示的格式(在
Jim
行后面有一个空行)或者你想让Joe和Rob在第2列中的值超过1的行的输出顺序重要吗?@markp fuso我的意思是说Joe和Rob的输出需要作为第二个输出打印在另一个文件中。@markp fuso我的意思是说第二组输出需要附加到一个文件中。看;我想你可以使用RavinderSingh13的
awk | split
,然后循环通过生成的数组来删除DUP。谢谢,Ravinder工作正常。你能告诉我你所做的代码吗。
$ cat single.out
Jim:44:cz
$ cat multiple.out
Joe:23;56:zz
Rob:45;98:fc