CSVのフィールドからカンマを削除する方法は?

CSVのフィールドからカンマを削除する方法は?

私は常に2番目のフィールド、nameというフィールド/列を持つCSVファイルで作業しています。

この列の値は、「Smith、John」、「Brady、Tom」、「Manning、Peyton」などです。

コンマ(「Smith John」や「Brady Tom」など)を使用せずにすべての項目を変更せずにこれを行うにはどうすればよいですか? sed awkを試してみましたが、理解できません。

答え1

示されているようにフィールドが正しく引用されている場合、挿入されたコンマは問題になりません(CSV認識パーサーを使用してデータを読み取ると仮定)。

それでも名前付きフィールドからカンマを削除する必要がある場合は、nameCSVをサポートするパーサーを使用してください。csvkitまたはミラーmlr)データ処理。

Millerを使用した例は次のとおりです。

mlr --csv put '$name = gsub($name, ",", "")' file.csv

その後、CSVからデータを読み込みfile.csv、見つかったものと同様の置換機能を使用して、名前付きawkフィールドからすべてのコンマを削除し、変更された可能性があるnameレコードを出力します。

例:

$ cat file.csv
age,name,note
47,"Hatter, Mad","Isn't actually ""mad"""
39,"Rabbit, White",Drinks too much tea
2,"Dormouse, The",Sleeps most of the time
$ mlr --csv put '$name = gsub($name, ",", "")' file.csv
age,name,note
47,Hatter Mad,"Isn't actually ""mad"""
39,Rabbit White,Drinks too much tea
2,Dormouse The,Sleeps most of the time

csvformat(csvkit から) と の場合、tr以下はドキュメントの区切り文字を一時的にセミコロンに変更してすべてのコンマを削除します。

csvformat -D ';' file.csv | tr -d , | csvformat -d ';'

例:

$ csvformat -D ';' file.csv | tr -d , | csvformat -d ';'
age,name,note
47,Hatter Mad,"Isn't actually ""mad"""
39,Rabbit White,Drinks too much tea
2,Dormouse The,Sleeps most of the time

csvsqlまたは(csvkitでも)一部のSQLを介してフィールドからコンマを削除するために使用できます。name

csvsql --query 'UPDATE file SET name = REPLACE(name, ",", "")' \
    --query 'SELECT * FROM file' file.csv

答え2

次のCSVが与えられた場合@Kusalanandaの返信:

$ cat file.csv
age,name,note
47,"Hatter, Mad","Isn't actually ""mad"""
39,"Rabbit, White",Drinks too much tea
2,"Dormouse, The",Sleeps most of the time

awkを使用すると、簡潔で壊れやすい方法があります(最初のフィールドも引用符または2番目のフィールドにエスケープされた引用符が含まれている場合は中断されます)。

$ awk 'BEGIN{FS=OFS="\""} {sub(/,/,"",$2)} 1' file.csv
age,name,note
47,"Hatter Mad","Isn't actually ""mad"""
39,"Rabbit White",Drinks too much tea
2,"Dormouse The",Sleeps most of the time

あまり簡潔ではないが強力なもの(フィールド内の引用符が各フィールドを倍増してエスケープされると仮定し、改行文字を除くすべてのフィールドの内容に対して機能します)RFC 4180) GNU awkを使うFPAT

$ awk 'BEGIN{FPAT="([^,]*)|(\"([^\"]|\"\")*\")"; OFS=","} {sub(/,/,"",$2)} 1' file.csv
age,name,note
47,"Hatter Mad","Isn't actually ""mad"""
39,"Rabbit White",Drinks too much tea
2,"Dormouse The",Sleeps most of the time

どのようなものを使うべきかは、CSVの内容によって異なります。

参照するフィールドに改行文字が含まれている場合、または上記の最初のスクリプトが機能しないCSVがあり、GNU awkにアクセスできない場合は、別の解決策が必要です。例をご覧ください。awkを使用してcsvを効率的に解析する最も強力な方法は何ですか

答え3

@KusalanandaのCSVの例を借りて、デフォルトのCSVパーサーでRubyを使用できます。

$ ruby -r csv -e 'data=CSV.parse($<.read, **{:headers=>true})
data["name"]=data["name"].map{|e| e.gsub(/,/,"")}
puts data' file.csv
age,name,note
47,Hatter Mad,"Isn't actually ""mad"""
39,Rabbit White,Drinks too much tea
2,Dormouse The,Sleeps most of the time

または、名前を変更してカンマなしでよりよくフィットさせるには、次の手順を実行します。

$ ruby -r csv -e 'data=CSV.parse($<.read, **{:headers=>true})
data["name"]=data["name"].map{|e| e.split(/,\s*/,2).reverse.join(" ")}
puts data' file.csv
age,name,note
47,Mad Hatter,"Isn't actually ""mad"""
39,White Rabbit,Drinks too much tea
2,The Dormouse,Sleeps most of the time

答え4

使用幸せ(以前のPerl_6)

RakuのText::CSVモジュールを使用してCSVを解析します。

~$ raku -MText::CSV -e 'my @a = csv(in => $*IN, strict => True);  \
         @a.skip>>.[1] = @a.skip>>.[1].map: *.trans( "," => "");  \
         .join("\t").put for @a;'  <  file.csv

入力例(@Kusalanandaから):

age,name,note
47,"Hatter, Mad","Isn't actually ""mad"""
39,"Rabbit, White",Drinks too much tea
2,"Dormouse, The",Sleeps most of the time

上記のコードの指示に従って、読みやすくするためにタブ区切りの列出力が下に表示されます(代わりにCSVファイル生成を使用join(","))。

出力例(1)

age name    note
47  Hatter Mad  Isn't actually "mad"
39  Rabbit White    Drinks too much tea
2   Dormouse The    Sleeps most of the time

列に空白がある場合、問題がある場合.trimなどを使用できます。また、OP は 2 列目の内容を反転して最初に名前を読み、次に姓を読み取ることもできます。もしそうなら、splitフィールドをカンマで囲むのがおそらく最善の方法でしょう。上記の最後のステートメントをに変更すると、csv(in => @a, out => $*OUT, sep_char => "\t")実際のTSV(またはCSV)ファイルが生成されます。

~$ raku -MText::CSV -e 'my @a = csv(in => "Mad_Hatter.csv", strict => True);  \
         @a.skip>>.[1] = @a.skip>>.[1].map: *.split(", ").reverse;  \
         csv(in => @a, out => $*OUT, sep_char => "\t");'  < file.csv

サンプル出力(2)

age name    note
47  "Mad Hatter"    "Isn't actually ""mad"""
39  "White Rabbit"  "Drinks too much tea"
2   "The Dormouse"  "Sleeps most of the time"

https://modules.raku.org/dist/Text::CSV:cpan:HMBRAND
https://github.com/Tux/CSV
https://raku.org

関連情報