0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

2023年12月10日: gawk 「-k」オプションなら クオートあり、改行あり CSV を正しく扱える件

Last updated at Posted at 2023-12-10

2023年12月10日: gawk 「-k」オプションなら クオートあり、改行あり CSV を正しく扱える件

GNU AWK のオプション -k または --csv を使うと、クオートあり、改行ありの CSV を正しく扱えることが分かったんでそのお試しメモ。

CSV 処理といえば FS="," だけど…

よくあるのが FS"," に設定する使い方。クオートがないCSVだったり、データとして改行を含まないCSVならこれで十分だけど、Excel だとかが出力する CSV って往々にして、クオートがあったり、データとして改行を含むもの。そうなるともう awk は選択しとしては現実的じゃなくなって、Perl でモジュールを使うだとかをすることになる。やりたいことはシンプルなのにお手軽に AWK を使えないのは残念過ぎる。

GNU AWK の「-k」オプション

GNU AWK のオプション -k または --csv を使うと、クオートあり、改行ありの CSV を正しく扱えるようになってた。いつの間にか。いくつかの入力データで試した。

お試しに使ったコードはこれ

print-fields.awk
{for (f=1 ; f<=NF ; ++f) printf "(%s)\n", $f}

基本サンプル

フィールド中のカンマも改行も期待どおりに処理されるのを確認できた。

% (echo ',"string contains ' ; echo 'Newline, and ' ; echo 'Newline",after comma') \
| gawk -k -f print-fields.awk
()
(string contains
Newline, and
Newline)
(after comma)
%

いい感じ。「and」に続くスペース文字の様子もみてみたら、ちゃんとできてた。

% (echo ',"string contains ' ; echo 'Newline, and ' ; echo 'Newline",after comma') \
| gawk -k -f print-fields.awk \
| sed -e 's/$/|/'
()|
(string contains |
Newline, and |
Newline)|
(after comma)|
%

NR はどおなる?

入力データのフィールド中に改行文字がある場合でも NR は増えてない。いいねっ。😀

% (echo ',"string contains ' ; echo 'Newline, and ' ; echo 'Newline",after comma') \
| gawk -k '{for (f=1 ; f<=NF ; ++f) printf "[NR=%d,f=%d]: (%s)\n", NR, f, $f}'
[NR=1,f=1]: ()
[NR=1,f=2]: (string contains
Newline, and
Newline)
[NR=1,f=3]: (after comma)
%

ダブルクオート中のダブルクオート「""

Excel が出力する CSV の表記法で、ダブルクオート中のダブルクオートを「""」表記する件。これにも対応してるっぽい。

% echo ',"""quote char in quoted string""",' \
| gawk -k -f print-fields.awk
()
("quote char in quoted string")
()
%

カンマの直後が「"」でない場合

これも Excel 方式に対応してるみたい。

% echo ', "quoted string starts end ends with space" ,' \
| gawk -k -f print-fields.awk
()
( "quoted string starts end ends with space" )
()
%

"」が閉じてない最後の行

これはファイルの一番最後に「"」がある場合と同じように処理されるっぽい。

% echo ', "unclosed quoted string starts with space,after comma' \
| gawk -k -f print-fields.awk
()
( "unclosed quoted string starts with space)
(after comma
)
%

カンマの直後が「"」でなくて、途中に「,」があって、「"」が閉じてない場合

この場合は、要するに、クオートされてない裸のフィールドと同じ処理になってるみたい?

% echo ', "unclosed quoted string starts with space,after comma' \
| gawk -k -f print-fields.awk
()
( "unclosed quoted string starts with space)
(after comma
)
%

改行シーケンス CR LF 問題

Excel から出力した CSV に対応してるみたい?改行シーケンス CR LF 問題はどおなのか、ためしてみたら、実行してる環境が Cygwin だからなのか、入力データ中の CR が無視されたみたいな結果になった。

% printf 'begin,"Hello,\r\nWorld.!",end\r\n' \
| gawk -k -f print-fields.awk \
| sed -z -e 's/\r/<CR>/g' \
| sed -z -e 's/\n/<LF>/g'
(begin)<LF>(Hello,<LF>World.!)<LF>(end)<LF>% 

おしまい

Excel から出力される CSV にもシッカリ対応できてるから、これはかなり実用性が上がったともう。いいねっ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?