私は常に2番目のフィールド、nameというフィールド/列を持つCSVファイルで作業しています。
この列の値は、「Smith、John」、「Brady、Tom」、「Manning、Peyton」などです。
コンマ(「Smith John」や「Brady Tom」など)を使用せずにすべての項目を変更せずにこれを行うにはどうすればよいですか? sed awkを試してみましたが、理解できません。
答え1
示されているようにフィールドが正しく引用されている場合、挿入されたコンマは問題になりません(CSV認識パーサーを使用してデータを読み取ると仮定)。
それでも名前付きフィールドからカンマを削除する必要がある場合は、name
CSVをサポートするパーサーを使用してください。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