Memfilter file .CSV berdasarkan nilai kolom 5 file dan mencetak catatan tersebut ke file baru


16

Saya memiliki file .CSV dengan format di bawah ini:

"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",""

Kolom ke-5 file memiliki string yang berbeda. Saya perlu memfilter file berdasarkan nilai kolom ke-5. Katakanlah, saya perlu file baru dari file saat ini yang hanya memiliki catatan dengan nilai "string 1" di bidang kelima.

Untuk ini saya mencoba perintah di bawah ini,

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

tapi itu membuat saya kesalahan sebagai berikut:

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

Saya kemudian menggunakan yang berikut ini yang memberi saya hasil yang aneh.

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

Keluaran:

"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: Saya menggunakan perintah toupper berada di sisi yang aman, karena saya tidak yakin apakah string akan berada dalam huruf kecil atau besar. Saya perlu tahu apa yang salah dengan kode saya dan apakah ruang dalam string penting saat mencari pola menggunakan AWK.

Jawaban:


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

Keluaran

"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",""

Saya pikir Inilah yang Anda inginkan.


Keluarannya persis seperti yang saya inginkan. Saya belum pernah berpikir untuk menjadikan '","'pembatas, jika tidak maka akan menyelesaikan masalah saya ... solusi hebat ...
Dhruuv

@ Dhruuv membuat '","'pembatas adalah jawaban terbanyak untuk pertanyaan Anda sebelumnya :).
terdon

@terdon: ya, saya tahu, tapi itu tidak masuk ke pikiran saya ketika saya mengalami masalah. Terus terang, saya pikir itu mungkin sesuatu dengan perintah atau sesuatu selain pembatas yang menyebabkan masalah ... :) Oleh karena itu tidak mencobanya ... :(
Dhruuv

2
@ Dhruuv tidak yakin tentang detailnya karena saya tidak tahu apa yang Anda coba lakukan tetapi kondisi Anda yang lain hampir pasti salah. Apakah Anda mencoba mencetak hanya jika $ 5 adalah HYPERION? Jika ya, coba else{if(toupper($5)=="HYPERION"){print}}. Tidak di komputer saya saat ini sehingga saya mungkin memiliki sintaks yang salah tetapi Anda tidak dapat memberikan kondisi untuk pernyataan lain.
terdon

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

2

Masalah dengan CSV adalah bahwa tidak ada standar. Jika Anda perlu sering berurusan dengan data berformat CSV, Anda mungkin ingin melihat metode yang lebih kuat daripada hanya menggunakan ","sebagai pemisah bidang Anda. Dalam kasus ini, Text::CSVmodul CPAN Perl sangat cocok untuk pekerjaan itu:

$ 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

Maaf untuk mengatakan tetapi, solusi Anda tidak mengembalikan catatan dari file ... Saya pikir hanya menambahkan pembatas seperti yang '","'akan dilakukan ... terima kasih ... :)
Dhruuv

@Mohsen -1 karena 1) Anda perlu melarikan diri dari "atau mereka tidak dipahami sebagai bagian dari pembatas file. Lihat jawaban untuk pertanyaan OP lainnya dan 2) Anda memisahkan blok BEGIN dari sisa perintah yang sepenuhnya hentikan itu Coba awk 'BEGIN {FS = "," }' '{print $0}', Anda akan melihat itu tidak menghasilkan output. Di masa depan, silakan menguji jawaban Anda untuk melihat apakah mereka benar-benar bekerja sebelum mempostingnya.
terdon
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.