2017-10-05 14 views
3

最初の列$1に基づいて行をマージし、出力をフォーマットしますか?ヘッダーを印刷するときに生成する必要がありますMax Unique count of first field. たとえば、アンゴラはカウント= 3、ブラジルはカウント= 5、ザンビアはカウント= 1と表示されます。 フィールド$ 1の最大ユニークカウントは5です。したがって、ヘッダーを5回印刷してすべてのフィールドに適切なヘッダーを付ける必要があります。awkは列に基づいて行をマージする

出力を印刷している間に、original input fileの注文を維持します。 にするために使用私の実際の入力ファイルは10の分野、12枚の分野など

Input.csv

Output.csv

現在
Country,Network,Details,Amount,Country,Network,Details,Amount,Country,Network,Details,Amount,Country,Network,Details,Amount,Country,Network,Details,Amount 
Angola,voda,xxx,10,Angola,at&t,xxx,20,Angola,mtn,xxx,30 
Brazil,voda,yyy,40,Brazil,voda,yyy,50,Brazil,at&t,yyy,60,Brazil,mtn,yyy,70,Brazil,voda,yyy,80 
Zambia,tcl,zzz,90 

を希望

Country,Network,Details,Amount 
Angola,voda,xxx,10 
Angola,at&t,xxx,20 
Angola,mtn,xxx,30 
Brazil,voda,yyy,40 
Brazil,voda,yyy,50 
Brazil,at&t,yyy,60 
Brazil,mtn,yyy,70 
Brazil,voda,yyy,80 
Zambia,tcl,zzz,90 

のように変わり、私は以下の2を使用しています実際の入力ファイルのフィールド数に基づいて、必要な出力を取得し、毎回手動でカウントを変更するコマンド。

手順:#1

awk 'BEGIN { while (count++<5) header=header "Country,Network,Details,Amount,"; print header }' > output.csv 

ステップ:第2位

awk -F, ' 
    /.+/{ 
     if (!($1 in Val)) { Key[++i] = $1; } 
     Val[$1] = Val[$1] $0 ","; 
    } 
    END{ 
     for (j = 1; j <= i; j++) { 
      print(Val[Key[j]]); 
     } 
    }' input.csv >> output.csv 

ご提案を探しています...

+0

|ソート '(あなたの入力データは国名でソートされているようです)?がんばろう。 – shellter

+0

そして...小さなサンプルデータ、必要な出力、そしてうんざりしたQのためにうまくいきます。投稿と幸運を続けてください! – shellter

答えて

4

awkワンライナー:

awk 'BEGIN{FS=OFS=","}FNR==1{n=$0;next}{a[$1]=($1 in a ? a[$1] OFS:"")$0; if(!($1 in b)){o[++i]=$1}; b[$1]++; mx=mx>b[$1]?mx:b[$1] }END{for(i=1; i<=mx; i++)printf("%s%s",n,i==mx?RS:OFS); for(i=1; i in o; i++)print a[o[i]]}' infile 

入力:

$ cat infile 
Country,Network,Details,Amount 
Angola,voda,xxx,10 
Angola,at&t,xxx,20 
Angola,mtn,xxx,30 
Brazil,voda,yyy,40 
Brazil,voda,yyy,50 
Brazil,at&t,yyy,60 
Brazil,mtn,yyy,70 
Brazil,voda,yyy,80 
Zambia,tcl,zzz,90 

出力:より良い

$ awk 'BEGIN{FS=OFS=","}FNR==1{n=$0;next}{a[$1]=($1 in a ? a[$1] OFS:"")$0; if(!($1 in b)){o[++i]=$1}; b[$1]++; mx=mx>b[$1]?mx:b[$1] }END{for(i=1; i<=mx; i++)printf("%s%s",n,i==mx?RS:OFS); for(i=1; i in o; i++)print a[o[i]]}' infile 
Country,Network,Details,Amount,Country,Network,Details,Amount,Country,Network,Details,Amount,Country,Network,Details,Amount,Country,Network,Details,Amount 
Angola,voda,xxx,10,Angola,at&t,xxx,20,Angola,mtn,xxx,30 
Brazil,voda,yyy,40,Brazil,voda,yyy,50,Brazil,at&t,yyy,60,Brazil,mtn,yyy,70,Brazil,voda,yyy,80 
Zambia,tcl,zzz,90 

読み取り可能:コメントを

awk 'BEGIN{ 
      FS=OFS="," 
    } 
    FNR==1{ 
      n=$0; 
      next 
    } 
    { 
      a[$1]=($1 in a ? a[$1] OFS:"")$0; 
      if(!($1 in b)){ o[++i]=$1 }; 
      b[$1]++; 
      mx=mx>b[$1]?mx:b[$1] 
    } 
    END{ 
      for(i=1; i<=mx; i++) 
       printf("%s%s",n,i==mx?RS:OFS); 

      for(i=1; i in o; i++) 
       print a[o[i]] 
    }' infile 

:私はする必要がない場合は

は、どこ 出力にのみ初めて「国」を印刷するには、コードを変更するには、知りたいです同じ国 名2回目、三回目を印刷

$ awk 'BEGIN{FS=OFS=","}FNR==1{n=$0;next}{a[$1]=($1 in a ? a[$1] OFS substr($0,index($0,",")+1) : $0); if(!($1 in b)){o[++i]=$1}; b[$1]++; mx=mx>b[$1]?mx:b[$1] }END{for(i=1; i<=mx; i++)printf("%s%s",i==1?n:substr(n,index(n,",")+1),i==mx?RS:OFS); for(i=1; i in o; i++)print a[o[i]]}' infile 
Country,Network,Details,Amount,Network,Details,Amount,Network,Details,Amount,Network,Details,Amount,Network,Details,Amount 
Angola,voda,xxx,10,at&t,xxx,20,mtn,xxx,30 
Brazil,voda,yyy,40,voda,yyy,50,at&t,yyy,60,mtn,yyy,70,voda,yyy,80 
Zambia,tcl,zzz,90 

改変コード:

awk 'BEGIN{ 
      FS=OFS="," 
    } 
    FNR==1{ 
      n=$0; 
      next 
    } 
    { 
      # this line modified 
      # look for char pos of comma, 

      a[$1]=($1 in a ? a[$1] OFS substr($0,index($0,",")+1) : $0); 

      if(!($1 in b)){ o[++i]=$1 }; 

      b[$1]++; 
      mx=mx>b[$1]?mx:b[$1] 
    } 
    END{ 
      for(i=1; i<=mx; i++) 
       # this line modified 
       printf("%s%s",i==1?n:substr(n,index(n,",")+1),i==mx?RS:OFS); 

      for(i=1; i in o; i++) 
       print a[o[i]] 
    }' infile 

変形に関する説明:

  • index(in, find)

文字列検索の最初の発生のための文字列を検索し、そして そのオカレンスが0から始まる位置で文字を返します。で文字列。

  • substr(string, start [, length ])

    戻り文字列の長さ、文字の長いストリング、 文字番号startから始まります。あなたが++ `OrderNum [$ 1]のような配列を保つ`と外側のループとしてごENDのprint文をドライブが、なぜ単に `のawk '{既存のPROGを}' を使用しないようにすることを追加することができます

+0

ありがとうAkshay Hegde、Up-voted !!! – SVR

+0

@RVS:注文番号が –

+0

に更新されました。同じ国名を2回目、3回目に印刷する必要がない場合は、コードを変更して「国」を初めて出力するように変更します。 – SVR

関連する問題