ファイルの5番目の列の値に基づいて.CSVファイルをフィルター処理し、それらのレコードを新しいファイルに出力します


16

次の形式の.CSVファイルがあります。

"column 1","column 2","column 3","column 4","column 5","column 6","column 7","column 8","column 9","column 10
"12310","42324564756","a simple string with a , comma","string with or, without commas","string 1","USD","12","70%","08/01/2013",""
"23455","12312255564","string, with, multiple, commas","string with or, without commas","string 2","USD","433","70%","07/15/2013",""
"23525","74535243123","string , with commas, and - hypens and: semicolans","string with or, without commas","string 1","CAND","744","70%","05/06/2013",""
"46476","15467534544","lengthy string, with commas, multiple: colans","string with or, without commas","string 2","CAND","388","70%","09/21/2013",""

ファイルの5列目には異なる文字列があります。5列目の値に基づいてファイルを除外する必要があります。たとえば、5番目のフィールドに値「string 1」のみを持つレコードを持つ現在のファイルから新しいファイルが必要だとしましょう。

このために、私は以下のコマンドを試しました、

awk -F"," ' { if toupper($5) == "STRING 1") PRINT }' file1.csv > file2.csv

しかし、それは私に次のようなエラーを投げていました:

awk: { if toupper($5) == "STRING 1") PRINT }
awk: ^ syntax error
awk: { if toupper($5) == "STRING 1") PRINT }
awk: ^ syntax error

次に、以下を使用しましたが、奇妙な出力が得られます。

awk -F"," '$5="string 1" {print}' file1.csv > file2.csv

出力:

"column 1" "column 2" "column 3" "column 4" string 1 "column 6" "column 7" "column 8" "column 9" "column 10
"12310" "42324564756" "a simple string with a comma" string 1 without commas" "string 1" "USD" "12" "70%" "08/01/2013" ""
"23455" "12312255564" "string with string 1 commas" "string with or without commas" "string 2" "USD" "433" "70%" "07/15/2013" ""
"23525" "74535243123" "string with commas string 1 "string with or without commas" "string 1" "CAND" "744" "70%" "05/06/2013" ""
"46476" "15467534544" "lengthy string with commas string 1 "string with or without commas" "string 2" "CAND" "388" "70%" "09/21/2013" ""

PS:文字列が小文字であるか大文字であるかわからないため、安全のためにtoupperコマンドを使用しました。コードの何が問題なのか、AWKを使用してパターンを検索するときに文字列のスペースが重要かどうかを知る必要があります。

回答:


17
awk -F '","'  'BEGIN {OFS=","} { if (toupper($5) == "STRING 1")  print }' file1.csv > file2.csv 

出力

"12310","42324564756","a simple string with a , comma","string with or, without commas","string 1","USD","12","70%","08/01/2013",""
"23525","74535243123","string , with commas, and - hypens and: semicolans","string with or, without commas","string 1","CAND","744","70%","05/06/2013",""

これがあなたの欲しいものだと思います。


出力は、まさに私がそれを必要としていた方法です。私が作ることを考えていない'","'...そう、それは私の問題を解決しているだろう...優れたソリューションを、区切り文字として
Dhruuv

@Dhruuv '","'が区切り文字を作成することは、前の質問に対するほとんどの答えが示唆したものです:)。
テルドン

@terdon:はい、知っていますが、私が問題を抱えていたとき、それは私の心には入りませんでした。率直に言って、私はそれが問題を引き起こしているコマンドまたはデリミタ以外のものであるかもしれないと思った... :)したがって、それを試していない... :(
Dhruuv

2
@Dhruuvは、あなたが何をしようとしているのかわからないので、詳細についてはわかりませんが、あなたの他の条件はほぼ間違いなく間違っています。5ドルがHYPERIONである場合、onyを印刷しようとしていますか?その場合は、試してくださいelse{if(toupper($5)=="HYPERION"){print}}。現時点では私のコンピューターではないため、構文が間違っている可能性がありますが、elseステートメントに条件を指定することはできません。
テルドン

1
awk -F '","' 'BEGIN {OFS=","} { if (NR==1) {print} else{if (toupper($5) == "STRING 1") print} }' file1
リモバラ

2

CSVの問題は、標準がないことです。CSV形式のデータを頻繁に処理する必要がある場合は","、フィールドセパレーターとして使用するだけでなく、より堅牢な方法を検討することをお勧めします。この場合、PerlのText::CSVCPANモジュールはこのジョブに非常に適しています。

$ perl -mText::CSV_XS -WlanE '
    BEGIN {our $csv = Text::CSV_XS->new;} 
    $csv->parse($_); 
    my @fields = $csv->fields(); 
    print if $fields[4] =~ /string 1/i;
' file1.csv
"12310","42324564756","a simple string with a , comma","string with or, without commas","string 1","USD","12","70%","08/01/2013",""
"23525","74535243123","string , with commas, and - hypens and: semicolans","string with or, without commas","string 1","CAND","744","70%","05/06/2013",""

-1
awk 'BEGIN {FS = "," }'  '{ (if toupper($5)  == "STRING 1") print; }'  file1.csv > file2.csv

言って申し訳ありませんが、あなたの解決策はファイルからレコードを返しません...ように区切り文字を追加するだけだと思い'","'ます...ありがとう... :)
Dhruuv

@Mohsen-1。1)「または、それらはファイル区切り文字の一部として理解されていない。エスケープする必要があります。OPの他の質問への回答を参照してください。2)BEGINブロックを残りのコマンド試してみてくださいawk 'BEGIN {FS = "," }' '{print $0}'、出力が生成されないことがわかります。将来的には、回答をテストして、投稿する前に実際に機能するかどうかを確認してください。
terdon
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.