Bir .CSV dosyasını bir dosyanın 5. sütun değerlerine göre filtreleyin ve bu kayıtları yeni bir dosyaya yazdırın


16

Aşağıdaki biçime sahip bir .CSV dosyası var:

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

Dosyanın 5. sütununda farklı dizeler var. 5. sütun değerine göre dosyayı filtrelemek gerekiyor. Diyelim ki, beşinci alanında yalnızca "dize 1" değeri ile kayıtları olan geçerli dosyadan yeni bir dosyaya ihtiyacım var.

Bunun için aşağıdaki komutu denedim,

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

ama bana aşağıdaki gibi bir hata veriyordu:

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

Daha sonra bana garip bir çıktı veren aşağıdakileri kullandım.

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

Çıktı:

"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: Ben dize küçük ya da büyük harf olacak emin değilim, toupper komutunu güvenli tarafında olmak için kullanılır. Benim kod ile neyin yanlış olduğunu bilmek ve AWK kullanarak bir desen ararken dize boşluk önemlidir.

Yanıtlar:


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

Çıktı

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

Sanırım istediğin bu.


Çıktı tam olarak olması gereken şeydi. '","'Sınırlayıcı olarak yapmayı düşünmedim , aksi takdirde sorunumu
çözerdi

@Druuvay '","'sınırlayıcı yapmak önceki soruya en çok cevap önerilen nedir :).
terdon

@terdon: evet, biliyorum, ama bu sorunu yaşadığımda aklıma gelmedi. Açıkçası, bunun komutla ilgili bir şey olabileceğini veya soruna neden olan sınırlayıcılardan başka bir şey olabileceğini düşündüm ... :) Bu nedenle denemedim ... :(
Dhruuv

2
@Druuv detaylar hakkında emin değilim çünkü ne yapmaya çalıştığınızı söyleyemem ama başka durumunuz neredeyse kesinlikle yanlış. 5 dolar HYPERION ise ony yazdırmaya mı çalışıyorsunuz? Varsa, deneyin else{if(toupper($5)=="HYPERION"){print}}. Şu anda bilgisayarımda değil, bu yüzden sözdizimi yanlış olabilir ama başka bir ifadeye bir koşul veremezsiniz.
terdon

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

2

CSV ile ilgili sorun, standart olmamasıdır. CSV biçimli verilerle sık sık ilgilenmeniz gerekiyorsa, yalnızca ","alan ayırıcı olarak kullanmak yerine daha sağlam bir yönteme bakmak isteyebilirsiniz . Bu durumda, Perl'in Text::CSVCPAN modülleri işe son derece uygundur:

$ 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

Üzgünüm ama, çözümünüz dosyadan herhangi bir kayıt döndürmüyor ... Sanırım sadece ayırıcıyı '","'yapacağınız gibi ekliyorum ... teşekkürler ... :)
Dhruuv

@Mohsen -1 çünkü 1) kaçmanız gerekiyor "veya dosya sınırlayıcısının bir parçası olarak anlaşılmıyorlar. OP'nin diğer sorusunun yanıtlarına bakın ve 2) BEGIN bloğunu komutun geri kalanından tamamen ayırdığınız Deneyin awk 'BEGIN {FS = "," }' '{print $0}', çıktı üretmediğini göreceksiniz.Gelecekte, cevaplarınızı göndermeden önce gerçekten işe
yarayıp
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.