特定の文字列間の引用符の検索と追加

特定の文字列間の引用符の検索と追加

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ファイルの|形式は - 文字を区切り文字として使用することから、デフォルトのカンマを区切り文字として使用することに戻ります。これにより、参照する必要があるフィールドが正しく参照されます。

これはまた、改行を含むフィールドを正しく処理します。

$ 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'[|]'入力フィールドの区切り文字を定義します。出力フィールドの区切り文字を定義します
。入力フィールド区切り記号(FS)に基づいて各行/レコードのフィールド数を決定するため、フィールド数を繰り返し、各フィールドに二重引用符を追加し、その行に最終更新を印刷します。-v OFS=','
NF変な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

関連情報