二重引用符の間の文字のみをsedまたはawkに置き換えます。

二重引用符の間の文字のみをsedまたはawkに置き換えます。

このシナリオはCSVファイルにあります。

ID,PRICE,QUANTITY,ARRIVAL
01299,"41,5",1,0
26528,"412,03",0,0
38080,"2,35",0,0
38081,"2,35",0,0
..
..

私が自分で尋ねる質問は次のとおりです。をどのように変更できますか?ただし,.価格のみ二重引用符で囲まれた列に対してのみ"..."可能PRICEですか?

私は前に試しました

sed -i 's/\(,\)[^ ]*\( .*\)/\1"."\2/'

しかし、成功しなかった場合はヒントを与えることができますか?

答え1

正規表現を拡張するには、sedの「-E」オプションを使用することをお勧めします。引用符の間に数字しかない場合は、次のことができます。

~ $ cat foo
lorem, ipsum
"5,25", foobar
"foo,bar", foobar
~ $ cat foo | sed -E 's/"([0-9]+)\,([0-9]+)"/"\1.\2"/g'
lorem, ipsum
"5.25", foobar
"foo,bar", foobar

引用符に大文字と小文字が含まれている場合は、次のように正規表現を拡張できます。

~ $ cat foo | sed -E 's/"([0-9]+|[a-z]+|[A-Z]+)\,([0-9]+|[a-z]+|[A-Z]+)"/"\1.\2"/g'
lorem, ipsum
"5.25", foobar
"foo.bar", foobar

regex101.comで正規表現を簡単にテストできます。参照:https://regex101.com/r/mlfSmp/1

答え2

csvformat以下で使用csvkit:

$ csvformat -D ';' file | tr , . | csvformat -d ';'
ID,PRICE,QUANTITY,ARRIVAL
01299,41.5,1,0
26528,412.03,0,0
38080,2.35,0,0
38081,2.35,0,0

上記のコマンドは、CSV区切り文字をデフォルトのコンマからセミコロンに変更します。次に、残りのコンマをドットに変更し、フィールド区切り文字をコンマに戻します。

または、次のコマンドを使用してCSVをJSONに変換し、csvjsonデータを変更しますjq

$ csvjson -I file | jq -r '(.[0] | keys_unsorted | @csv), (map(.PRICE |= sub(",";".") | [.[]] | @csv)[])'
"ID","PRICE","QUANTITY","ARRIVAL"
"01299","41.5","1","0"
"26528","412.03","0","0"
"38080","2.35","0","0"
"38081","2.35","0","0"

csvformat不要な引用符を削除するには、引数なしでこの引数を渡します。

このjq式は、最初に入力配列の最初のオブジェクトからキーを取得し、ヘッダーを出力します。次に、各要素のフィールドを変更しPRICE(コンマをドットに変更し)、出力のために値をCSVにフォーマットします。

2番目の変形と1番目の変形の効果の違いは、熱にのみ影響することですPRICE。他のフィールドに含まれるカンマは変更されません。


参考として、質問のCSVデータを考慮して、次のjqJSONドキュメントを参照してください。csvjson

[
  {"ID":"01299","PRICE":"41,5","QUANTITY":"1","ARRIVAL":"0"},
  {"ID":"26528","PRICE":"412,03","QUANTITY":"0","ARRIVAL":"0"},
  {"ID":"38080","PRICE":"2,35","QUANTITY":"0","ARRIVAL":"0"},
  {"ID":"38081","PRICE":"2,35","QUANTITY":"0","ARRIVAL":"0"}
]

答え3

これを調整する回答到着カンマで区切られたファイルから引用符の間のカンマのみを削除します。解決策awk

awk -F'"' -v OFS='"' '{ for (i=2; i<=NF; i+=2) gsub(",", ".", $i) } 1' infile

infileどこ

ID,PRICE,QUANTITY,ARRIVAL
01299,"41,5",1,0
26528,"412,03",0,0
38080,"2,35",0,0
38081,"2,35",0,0

明らかにする

ID,PRICE,QUANTITY,ARRIVAL
01299,"41.5",1,0
26528,"412.03",0,0
38080,"2.35",0,0
38081,"2.35",0,0

コードの説明は引用された答えと同じですので、以下を除いては繰り返しません。

  • 出力フィールド区切り文字は、空の(たとえば")の代わりにOFS='"'(たとえばOFS='')です。
  • 次に、gsubカンマ(",")を"."スペース()の代わりにピリオド("")に置き換えます。

関連情報