แทนที่ขีดล่างด้วยเครื่องหมายจุลภาคและลบเครื่องหมายคำพูดคู่ใน CSV


10

ฉันมีไฟล์ CSV เป็น

input.csv

"1_1_0_0_76"
"1_1_0_0_77"
"1_1_0_0_78"
"1_1_0_0_79"
"1_1_0_0_80"
"1_1_0_0_81"
"1_1_0_0_82"
"1_1_0_0_83"
"1_1_0_0_84"
"1_1_0_0_85"

............. เป็นต้น

ฉันต้องการแปลงไฟล์ CSV นี้เป็น

result.csv 

1,1,0,0,76
1,1,0,0,77
1,1,0,0,78
1,1,0,0,79
1,1,0,0,80
1,1,0,0,81
1,1,0,0,82
1,1,0,0,83
1,1,0,0,84
1,1,0,0,85

คำตอบ:


24

วิธีที่ง่ายกว่านั้นคือการใช้ tr

$ tr '_' ',' < input.csv | tr -d '"'                  
1,1,0,0,76
1,1,0,0,77
1,1,0,0,78

วิธีการทำงานนี้trใช้สองอาร์กิวเมนต์ - ชุดอักขระที่จะถูกแทนที่และการแทนที่ ในกรณีนี้เรามีเพียง 1 ชุดเท่านั้น เราเปลี่ยนเส้นทางสตรีมinput.csvอินพุตtrstdin ผ่าน<โอเปอเรเตอร์ของเชลล์และไพพ์ผลลัพธ์ที่ส่งไปtr -d '"'ยังเพื่อลบเครื่องหมายคำพูดคู่

แต่ก็awkสามารถทำได้เช่นกัน

$ cat input.csv
"1_1_0_0_76"
"1_1_0_0_77"
"1_1_0_0_78"
$ awk '{gsub(/_/,",");gsub(/\"/,"")};1' input.csv
1,1,0,0,76
1,1,0,0,77
1,1,0,0,78

วิธีนี้การทำงานแตกต่างกันเล็กน้อย: awk /Pattern match/{ codeblock}/Another pattern/{code block for this pattern}อ่านแต่ละบรรทัดไฟล์โดยสายแต่ละเส้นเป็นสคริปต์ ที่นี่เราไม่มีรูปแบบดังนั้นการรัน codeblock สำหรับแต่ละบรรทัด gsub()ฟังก์ชั่นจะใช้สำหรับการทดแทนทั่วโลกภายในหนึ่งบรรทัดดังนั้นเราจึงใช้มันเพื่อแทนที่ขีดล่างด้วยเครื่องหมายจุลภาคและเครื่องหมายคำพูดคู่ด้วยสตริง null (การลบอักขระอย่างมีประสิทธิภาพ) การแทนที่1อยู่ในรูปแบบตรงกับการบล็อกโค้ดที่หายไปซึ่งเป็นค่าเริ่มต้นเพียงพิมพ์บรรทัด; กล่าวอีกนัยหนึ่งคือ codeblock ด้วยgsub()ทำงานและ1พิมพ์ผลลัพธ์

ใช้การเปลี่ยนเส้นทางเชลล์ ( >) เพื่อส่งออกไปยังไฟล์ใหม่:

 awk '{gsub(/_/,",");gsub(/\"/,"")};1' input.csv > output.csv

ขอโทษฉันยังต้องการลบเครื่องหมายจุลภาคคว่ำด้วยฉันได้อัปเดตคำถาม
RKR

@RKR คำตอบอัพเดทแล้วคำตอบของ Ian ยังได้รับการปรับปรุงด้วย
Sergiy Kolodyazhnyy

13

คุณสามารถใช้sedคำสั่งนี้แทน:

$ sed -e 's/_/,/g' -e 's/"//g' input.csv
1,1,0,0,76
1,1,0,0,77
1,1,0,0,78

1
ภายในเครื่องหมายคำพูดเดี่ยวคุณไม่จำเป็นต้องหลีกเลี่ยงคำพูดซ้ำ
เกล็

แน่นอน @glennjackman! ฉันเพิ่งลบเครื่องหมายแบ็กสแลชที่กำลังหลบหนีออกไป
IanC

10

Perl, "คลั่งกองทัพสวิส" ของการประมวลผลข้อความบรรทัดคำสั่งยังสามารถทำได้ ไวยากรณ์คือ (ไม่บังเอิญ) ค่อนข้างคล้ายกับtrและsedตัวอย่าง:

perl -pe 'tr/_"/,/d' input.csv > result.csv

หรือ:

perl -pe 's/_/,/g; s/"//g' input.csv > result.csv

แต่จริงๆแล้วถ้าคุณไม่ต้องการใช้เวลาในการเรียนรู้ภาษาการเขียนโปรแกรมใหม่ (ซึ่งจริงๆแล้วคืออะไร awk, Perl และ sed และเครื่องมืออื่น ๆ เช่นพวกเขา) เพียงแค่สำหรับงานพื้นฐานนี้คุณก็สามารถทำได้เช่นกัน เครื่องมือแก้ไขข้อความใด ๆ ที่รองรับการค้นหาและแทนที่:

  1. เปิดไฟล์ CSV ในโปรแกรมแก้ไขข้อความที่คุณชื่นชอบ (เช่น gedit, kate, mousepad เป็นต้นแม้แต่แม้แต่ Notepad ธรรมดาหรือ Wordpad บน Windows ก็สามารถทำได้)

  2. เลือก "ค้นหาและแทนที่" จากเมนู (โดยทั่วไปจะอยู่ใต้ "แก้ไข" หากไม่มีเมนู "ค้นหา" แยกต่างหาก)

  3. ใส่_ลงในช่องค้นหาและ,ในช่องเปลี่ยน

  4. คลิก "แทนที่ทั้งหมด"

  5. ทำซ้ำกับ"ในช่องค้นหาและไม่มีอะไรในกล่องเปลี่ยน

  6. บันทึกไฟล์

ทีนี้ถ้าคุณต้องการทำสิ่งนี้กับไฟล์ 100 หรือ 1,000 ไฟล์แทนที่จะเป็นไฟล์เดียวการเรียนรู้เครื่องมือบรรทัดคำสั่งใหม่จะเริ่มต้นขึ้น และแน่นอนเมื่อคุณรู้วิธีใช้ Perl หรือ sed หรืออะไรก็ตามคุณจะประหยัดเวลาและความพยายามด้วยงานที่คล้ายกันในภายหลัง แต่สำหรับงานเพียงครั้งเดียวที่คุณไม่คาดหวังว่าจะต้องทำอีกครั้งบางครั้งเครื่องมือโต้ตอบพื้นฐานเช่นโปรแกรมแก้ไขข้อความเป็นวิธีแก้ปัญหาที่ง่ายที่สุด


3

คุณสามารถทำได้ด้วยvimเช่นกัน

เปิดแฟ้ม: vim input.csvแล้วใช้ของเครื่องมือในการค้นหาขั้นสูงvim sพิมพ์ colon ( :) เพื่อเข้าสู่โหมดคำสั่งและเรียกใช้คำสั่งดังนี้:

:%s's/_/,/g'  -- Replaces all occurrences of _ with , in the current file.
:s/\"//g -- Replaces all occurrences of " with nothing in the current file.

สวยมากคำสั่งเช่นเดียวกับในคำตอบ IanC แต่ภายในของแทนการใช้vimsed


2

ทำไมไม่เปลี่ยนค่าเริ่มต้นของค่าตัวคั่นอินพุตและเอาต์พุต

awk -F "_" 'BEGIN { OFS="," }; {gsub(/\"/,""); print $1,$2,$3,$4,$5}' input.csv
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.