mappings.csv
以下のようにCSVがあります。 null以外の最初のフィールドを持つ各レコードに関連する別々のファイルにレコードの塊を抽出したいと思います。ファイルが次に表示されますmappings.csv
。
$ cat mappings.csv
TEST1,,,a,a,a,a
,,,b,b,b,b
,,,c,c,c,c
TEST2,,,aa,aa,aa,aa
,,,bb,bb,bb,bb
,,,cc,cc,cc,cc
,,,dd,dd,dd,dd
TEST3,,,aaa,aaa,aaa,aaa
,,,bbb,bbb,bbb,bbb
出力ファイルはmappings.csv
以下に基づいています。
$ cat TEST1.csv
TEST1,,,a,a,a,a
,,,b,b,b,b
,,,c,c,c,c
$ cat TEST2.csv
TEST2,,,aa,aa,aa,aa
,,,bb,bb,bb,bb
,,,cc,cc,cc,cc
,,,dd,dd,dd,dd
$ cat TEST3.csv
TEST3,,,aaa,aaa,aaa,aaa
,,,bbb,bbb,bbb,bbb
awkを使用して、null以外の最初のフィールドを持つ行を印刷できますが、次のnull以外の最初のフィールドまで後続のレコードを展開して印刷する方法はわかりません。
$ awk -F',' '$1' mappings.csv
TEST1,,,a,a,a,a
TEST2,,,aa,aa,aa,aa
TEST3,,,aaa,aaa,aaa,aaa
この問題の別の側面は、結果を別々のファイルに分割することです。私ができることの1つは、レコード番号に一致する行を印刷することです。このような:
$ awk -F',' '$1 {print NR}' mappings.csv
1
4
8
答え1
以前も非常によく似た質問が提起され、回答されましたが、たとえば次のようになります。
指定された列のNULL以外の値からのみファイル名を取得できる正確な重複エントリが見つかりません。だから与えられた:
$ cat mappings.csv
TEST1,,,a,a,a,a
,,,b,b,b,b
,,,c,c,c,c
TEST2,,,aa,aa,aa,aa
,,,bb,bb,bb,bb
,,,cc,cc,cc,cc
,,,dd,dd,dd,dd
TEST3,,,aaa,aaa,aaa,aaa
,,,bbb,bbb,bbb,bbb
それから
awk -F, '$1 != "" {close(f); f = $1 ".csv"} {print > f}' mappings.csv
明らかにする
$ head TEST*
==> TEST1.csv <==
TEST1,,,a,a,a,a
,,,b,b,b,b
,,,c,c,c,c
==> TEST2.csv <==
TEST2,,,aa,aa,aa,aa
,,,bb,bb,bb,bb
,,,cc,cc,cc,cc
,,,dd,dd,dd,dd
==> TEST3.csv <==
TEST3,,,aaa,aaa,aaa,aaa
,,,bbb,bbb,bbb,bbb
最初の操作では、名前付きファイルを閉じてからf
(開いたファイルがある場合)、f
最初のフィールドの(null以外)値をsuffixに関連付けて$1
新しい値を設定します.csv
。 2番目のジョブは、変数の(現在の)値というファイルにレコードを印刷しますf
。空の場合、エラーが報告されますf
。これは行がある場合に発生します。今後NULL以外の最初の値$1
。
一部のawk実装はファイルのクローズを処理する可能性があり、その場合は明示的に行う必要はありませんclose(f)
。