กรองไฟล์. CSV ตามค่าคอลัมน์ที่ 5 ของไฟล์และพิมพ์บันทึกเหล่านั้นลงในไฟล์ใหม่


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 ให้บอกว่าฉันต้องการไฟล์ใหม่จากไฟล์ปัจจุบันที่มีการบันทึกเฉพาะกับค่า "สตริง 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

@terdon: ใช่ฉันรู้ แต่นั่นไม่ได้อยู่ในใจของฉันเมื่อฉันมีปัญหา ตรงไปตรงมาฉันคิดว่ามันอาจเป็นสิ่งที่มีคำสั่งหรือสิ่งอื่นนอกเหนือจากตัวคั่นที่ทำให้เกิดปัญหา ... :) ดังนั้นจึงไม่ได้ลอง ... :(
Dhruuv

2
@ Dhruuv ไม่แน่ใจเกี่ยวกับรายละเอียดเพราะฉันไม่สามารถบอกได้ว่าคุณกำลังพยายามทำอะไรอยู่ คุณพยายามพิมพ์ด้วยราคา $ 5 คือ HYPERION หรือไม่? else{if(toupper($5)=="HYPERION"){print}}ถ้าเป็นเช่นนั้นลอง ไม่ใช่ที่คอมพิวเตอร์ของฉันในขณะนี้ดังนั้นฉันอาจมีไวยากรณ์ผิด แต่คุณไม่สามารถให้เงื่อนไขกับคำสั่งอื่นได้
terdon

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

2

ปัญหาของ CSV คือไม่มีมาตรฐาน หากคุณต้องการจัดการกับข้อมูลที่จัดรูปแบบ CSV บ่อยครั้งคุณอาจต้องการวิธีที่มีประสิทธิภาพมากกว่าแทนที่จะใช้","เป็นตัวคั่นฟิลด์ ในกรณีนี้Text::CSVโมดูล CPAN ของ Perl เหมาะอย่างยิ่งกับงาน:

$ 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.