フィールド内も行セパレータも両方とも 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 じゃない場合
とか。