特定の文字列の間に引用符を見つけて追加する

特定の文字列の間に引用符を見つけて追加する

csv を操作しているときに、不要なカンマ (',') が csv ファイルに誤解を招き、結果として不整合が生じます。

詳細は下記をご覧ください。

私のサンプル csv ファイル:

1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4

最終結果は次のようにしたい:

1|"a,b"|4
1|"c,d"|4
1|"e,f"|4
1|"g,h"|4
1|"i,j"|4

引用符を追加した後、「|」を「、」に置き換えて、csv が期待どおりに動作するようにします。

以下のコマンドを使用しましたが、期待どおりに動作しません。

sed -e 's/,/"&"/' file1.txt

答え1

csvformatからの使用csvkit、そして最終結果は、質問の本文で説明されているように、区切り文字としてコンマが使用された CSV ファイルになるものと仮定します。

$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4

これにより、CSV ファイルの|区切り文字が -characters からデフォルトのコンマに再フォーマットされます。これにより、引用符で囲む必要があるフィールドが適切に引用符で囲まれます。

これは、埋め込まれた改行を含むフィールドも適切に処理します。

$ cat file
1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4
2|"line 1,
line2"|5
$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
2,"line 1,
line2",5

CSV、JSON、XML、YAML、TOMLなどの構造化されたドキュメント形式のドキュメントがある場合は、ないそのドキュメント形式用のパーサーを使用してそのドキュメントを解析します。

答え2

次のようにすることができます:

awk -F'[|]' -v OFS=',' -v q='"' '{ for(i=1; i<=NF; i++) $i=q $i q }1' infile

-F'[|]'入力フィールドセパレーターを定義しました。
-v OFS=','出力フィールドセパレーターを定義しました。
NFFS (入力フィールドセパレーター) に基づいて各行/レコードにいくつのフィールドがあるかを識別するので、フィールドの数をループしてそれぞれに二重引用符を追加し、最終更新を次の行に出力します。awk の1イディオム印刷用です。

このコマンドではすべてのフィールドが引用符で囲まれますが、これは有効な CSV ファイルを作成する上で問題ではないことに注意してください。

答え3

sed

$ sed 's/[^|]*,[^|]*/"&"/g; y/|/,/' ip.txt
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
  • s/[^|]*,[^|]*/"&"/gすべてのフィールドに二重引用符を追加します,
  • y/|/,/すべての|文字を,

perl

perl -F'\|' -lane 'print join ",", map {/,/ ? qq("$_") : $_} @F'

これは|入力フィールドの区切り文字として使用されます。次に、mapを含むすべてのフィールドに二重引用符を追加します,。最後に、は文字joinでフィールドを結合するために使用されます,

答え4

別のsed方法:

  sed 's;\([^|]*\)|\([^|]*\)|\(.*\)$;\1,"\2",\3;' data

または、などのsedの読み込みをサポートしている場合は、すべてのエスケープ処理を回避できます。EREGNU sed

  sed -E 's;([^|]+)\|([^|]+)\|(.+)$;\1,"\2",\3;' data

|各境界で中間のグループのみが a によって区切られるという事実を利用して、sedさらに短くすることができます。

sed 's;|\([^|]*\)|;,"\1",;' data

もちろん、ここでも、sedがサポート-EされていればERE、面倒なエスケープジョブを回避できます。

関連情報