行の列数に基づいてCSVをソートしますか?

行の列数に基づいてCSVをソートしますか?

多くのレコードを含む複数のCSVファイルがあります。総行数は134個でなければなりません。多くのファイルがあり、各行には固有の列数(15〜200個)があります。列数に基づいてソートする必要があります。

以下を使用して、ファイル内の列数を数えることができます。

$ awk -F"," '{print NF}' file # 1.csv

...次の内容を提供します。

134
134
134
5
25
133
...

今後、それに基づいて行をソートできるように、各行にこの数字を追加したいと思います。各情報の先頭にこの情報を追加して並べ替えるにはどうすればよいですか?

また、値が134のファイルをそれぞれの数に応じて別のファイル1つに分割したいと思います。

小さな入力ファイルの例(合計3行):

2,"A.B.C.D",50,"SDf3oa701-ab73-a0pcs90","7012218969217-1413752517-32448","SDf3oa701-ab73-a0pcs90","SIP",,"<[email protected]>;tag=70122","<[email protected]>",17,0,"00:01:57.827 GMT Oct 20 2014","00:00:00.000 UTC Jan 01 1970","00:01:57.870 GMT Oct 20 2014",3,"sp3",1904,"sp3",1904,"realm_IN","realmTERM_OUT",,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,"Sw-buildabcd","GMT-03:00",0,"[email protected]",,,,,,"X.Y.Z.W:50","A.S.D.F:50","A.S.D.F:50","A.S.D.F:50",,1,2,1,404,"[email protected]",,,4493101
2,"A.B.C.D",50,,,,4493105
2,"A.B.C.D",50,,"[email protected]",,,4493106

答え1


これを追加したいカンマ区切りと考えてください-F,
例えばawk -F, '$(NF+1)=NF' file

行末に数字を追加

 awk '$(NF+1)=NF' file

入力する

1
1 2 3
1 2
1 2 3 4 5 6
a b

出力

1 1
1 2 3 3
1 2 2
1 2 3 4 5 6 6
a b 2

行の並べ替え

 awk '{a[NF]=a[NF]?a[NF]"\n"$0:$0;x=x<NF?NF:x}END{for(i=1;i<=x;i++)if(i in a)print a[i]}'

入力する

1
1 2 3
1 2
1 2 3 4 5 6
a b

出力

1
1 2
a b
1 2 3
1 2 3 4 5 6

別のファイルに印刷

たとえば、フィールドの長さ4を使用して134または希望の値に変更します。

 awk '{print > (NF>=4?"LargeFile.txt":"SmallFile.txt")}' file 

入力する

1
1 2 3
1 2
1 2 3 4 5 6
a b

出力

LargeFile.txt

 1 2 3 4 5 6

SmallFile.txt

1
1 2 3
1 2
a b

答え2

@terdonの答えに似ていますが、次のものが含まれていますsed

{ seq -s, 10; seq -s, 5; seq -s, 15; } | 
tee - -

これは私の情報ファイルです。次のようになります。

1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

その後、次のようにできます。

sed 'h;s/[^,]*//g;G;s/\n/ /' | sort -t\  -nk1,1

...これは...

,,,, 1,2,3,4,5
,,,, 1,2,3,4,5
,,,, 1,2,3,4,5
,,,,,,,,, 1,2,3,4,5,6,7,8,9,10
,,,,,,,,, 1,2,3,4,5,6,7,8,9,10
,,,,,,,,, 1,2,3,4,5,6,7,8,9,10
,,,,,,,,,,,,,, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
,,,,,,,,,,,,,, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
,,,,,,,,,,,,,, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

数字はありませんが、数字は確実だと思います。前のカンマを削除するには、次のようにします。

PIPELINE | sed 's/,* //'

...これは...

1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

これまでの最も控えめな答えではないかもしれませんが、私がこの投稿を書くことにした主な理由は、カンマ区切りの134項目を含む行を別のファイルに書きたいと言っていたからです。偶然にもこれは簡単なことですsed。たとえば、上記のシーケンスの10個のフィールドを含む行を次のように作成するとしますfile2

PIPELINE | sed '/^\([^,]*,[^,]*\)\{9\}$/w file2'
cat file2

出力

1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10

\{9\}上記の方法はパターンの9つのインスタンスを指定するために使用しました。つまり、9つの区切り文字を10の区切りフィールドにします。範囲は次のように簡単に処理できます。

PIPELINE | sed '/^\([^,]*,[^,]*\)\{4,9\}$/w file2'
cat file2

出力

1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10

答え3

次に、各行の先頭に(カンマで区切られた)フィールドの数を追加し、行を印刷してすべてを並べ替えます。

awk -F"," '{print NF,$0}' *csv | sort -nk1,1

これは-n数値順に並べ替え、-k1,1最初のフィールドでのみ並べ替えるようにします。ソートされたフィールドの数を削除するには、次のようにします。

awk -F"," 'print NF,$0' *csv | sort -nk1,1 | cut -d ' ' -f 2- 

ノート:実際のデータによっては簡単に壊れることがあります。フィールドにカンマを含めることはできますか?複数行にまたがるフィールドを持つことはできますか?これは問題を解決できない非常に素朴なアプローチです。

関連情報