フィールド内も行セパレータも両方とも LF
だともはや AWK
の仕事ではないと思うので、
ExcelからエクスポートしたCSV
に限定して処理してみようと思う。
- 行セパレータは
CR+LF
- フィールド内に
LF
(セル内でAlt + Enter
してできるやつ) を含む - フィールド内に
LF
を含む場合、""
で囲まれている
RS="\r\n"
を設定し、フィールド内のLF
で行分割されないようにするFPAT="[^,]+|\"[^\"]+\""
を設定し、フィールド内にLF
を許容する- フィールド内の
LF
を適当な文字列に置換して表示させてみる
$ cat linebreak_in_fields.csv
a,"b
",c
1,"2
",3
$ cat linebreak_in_fields.csv | tr "\r\n" "^@"
a,"b@",c^@1,"2@",3^@
条件のとおりになっている。
$ ./linebreak_in_fields.awk linebreak_in_fields.csv
a --> "b<LF>" --> c
1 --> "2<LF>" --> 3
うまくいった。
FPATがおかしかったので直す。
あと、LF
はどうやら AWK
においては /./
でマッチさせられる模様
$ awk 'BEGIN{print ("\n" ~ /./)}'
1
$ awk 'BEGIN{print ("\r" ~ /./)}'
1
$ awk 'BEGIN{print ("\t" ~ /./)}'
1
$ awk 'BEGIN{print (" " ~ /./)}'
1
ということは FPAT="[^,]+|\"[^\"]+\""
これでいいはずだ
ちなみにPerlだと m//s
オプションを使わないとダメ
$ perl -Wle '{ print (("\n" =~ m/./ ) ? 1 : 0) }'
0
$ perl -Wle '{ print (("\n" =~ m/./s) ? 1 : 0) }'
1
- マルチバイト文字を含む場合
- エンコードが UTF-8 じゃない場合
とか。