ฉันจะลบคำที่ 5 ของทุกบรรทัดในไฟล์ได้อย่างไร


13

ฉันต้องการลบคำที่ 5 ของแต่ละบรรทัดในไฟล์

เนื้อหาปัจจุบันของไฟล์:

File is not updated or and will be removed  
System will shut down f within 10 seconds  
Please save your work 55 or copy to other location  
Kindly cooperate with us D  

ผลลัพธ์ที่คาดหวัง:

File is not updated and will be removed  
System will shut down within 10 seconds  
Please save your work or copy to other location  
Kindly cooperate with us

คำตอบ:


31

เกี่ยวกับcut:

$ cut -d' ' -f1-4,6- file.txt 
File is not updated and will be removed  
System will shut down within 10 seconds  
Please save your work or copy to other location  
Kindly cooperate with us
  • -d' ' กำหนดตัวคั่นเป็นพื้นที่

  • -f1-4,6- เลือกฟิลด์แรกถึง 4 (คำ) ปล่อยให้ฟิลด์ที่ 5 จากนั้นพิมพ์ต่อจาก 6 ไปยังที่เหลือ


11

วิธีแก้ปัญหาด้วยcut:

cut -d ' ' -f1-4 -f6- FILE

หลายอย่าง-fไม่ได้รับการสนับสนุนในcut(GNU) ของฉันอย่างน้อย ..
heemayl

รองรับการตัด BSD แต่ฉันชอบคำตอบของคุณดีกว่าของฉัน
fd0

1
ถ้ามัน GNU ตัดคุณจะได้รับธงที่จะลดความซับซ้อนของสิ่ง:--complement cut --complement -d ' ' -f5อย่าลืมเปลี่ยนเส้นทางเอาต์พุตไปที่ไฟล์ใหม่จากนั้นเปลี่ยนmvทับไฟล์ต้นฉบับ
Toby Speight

6

awk: ลบฟิลด์ที่ 5

awk '{for (i=5; i<NF; i++) $i = $(i+1); NF--};1' file

หากคุณต้องการบันทึกไฟล์แบบแทนที่: /programming//q/16529716/7552

คุณสามารถลบเนื้อหาของฟิลด์ที่ 5 ได้ แต่จะทำให้มีตัวคั่นฟิลด์เอาต์พุตต่อเนื่องกัน 2 ตัว:

awk '{$5 = ""};1' file

ข้อแม้ที่นี่คือการเปลี่ยนค่าของเขตข้อมูลใด ๆ ใน awk มีผลข้างเคียงของการเขียนใหม่ทั้งหมด "$ 0" โดยมีเพียง 1 ตัวคั่นระหว่างแต่ละเขตข้อมูล ควรนำมาพิจารณาหากคุณต้องการที่จะจัดตำแหน่งใด ๆ (เว้นแต่ gnu awk มีตัวเลือกหลีกเลี่ยงปัญหานี้หรือไม่ปกติ awk / nawk จะคำนวณ $ 0)
Olivier Dulac

ในทั้งสองกรณีคุณฟอร์แมตบรรทัดใหม่ด้วยตัวคั่นเดี่ยว หากมี 2 ช่องว่างหรือเว้นวรรค + แท็บในตัวคั่นผลที่ได้คือพื้นที่เดียวในสถานที่ นี่เป็นเรื่องที่น่ายินดีสำหรับข้อความส่วนใหญ่
NeronLeVelu

4

ด้วย POSIX sed:

sed -e 's/[^[:alnum:]_][[:alnum:]_][[:alnum:]_]*//4' <file

ทำไม จำกัด ชั้นเรียนเพื่อ: alnum และ_ และไม่ได้อะไรอื่นแล้ว:blank:หรือ:space:?
NeronLeVelu

@NeronLeVelu: ขึ้นอยู่กับว่าคุณกำหนดสิ่งที่ทำให้คำ
cuonglm

@mikeserv; รับได้สวย! ฉันปรับปรุงคำตอบของฉัน
cuonglm

เป็นสิ่งที่\(กลุ่มจับ\)หา?
mikeserv

@mikeserv: การพิมพ์ผิดฉันได้ลองใช้วิธีการบางอย่างเพื่อรักษาตัวคั่น
cuonglm

2

Glennเสนอวิธีแก้ปัญหาที่เทียบเท่า

awk '{$ 5 = ""; ไฟล์ } พิมพ์ '

ในขณะที่เขาและคนอื่น ๆ ชี้ให้เห็นสิ่งนี้

  1. แถบชั้นนำและช่องว่างต่อท้ายจากทุกบรรทัด
  2. บีบอัดแต่ละช่องว่าง (ช่องว่างและ / หรือแท็บ) ลงในช่องว่างเดียวและ
  3. เว้นสองช่องว่างระหว่างคำที่สี่และหก

แฮ็คเพื่อแก้ไขปัญหาที่สามคือ

awk '{$ 5 = ""; พิมพ์} ' ไฟล์ | sed 's / / /'

การทำเช่นนี้จะทำให้มีช่องว่างเพิ่มอีกหนึ่งช่องหรือท้ายบรรทัดที่มีห้าคำหรือน้อยกว่านั้นหากคุณสามารถระบุคำที่ไม่เคยปรากฏในอินพุต

awk '{$ 5 = "ยูนิคอร์น"; พิมพ์} ' ไฟล์ | sed 's / * unicorn //'

จะจัดการแม้กระทั่ง (แต่ก็ยังทำให้เกิดปัญหา 1 และ 2)


2
 sed 's/^\(\([[:blank:]]*[^[:blank:]]\{1,\}\)\{4\}\)[[:blank:]]*[^[:blank:]]*/\1/' YourFile > Output.txt
  • posix sed ตามตัวคั่นช่องว่าง / แท็บ (คลาสเมตา [: blank:]])
  • รักษาช่องว่างต่อไปนี้หลังจากคำที่ 5 แต่ลบออกก่อน

มีประสิทธิภาพมากขึ้น (sed ใช้รูปแบบที่ยาวที่สุดที่เป็นไปได้และรูปแบบที่*อาจพลาดการแยกหรือคำในรุ่นแรก) แต่รุ่นที่ยาวกว่าเล็กน้อย

sed 's/^\([[:blank:]]*\([^[:blank:]]\{1,\}[[:blank:]]\{1,\}\)\{4\}\[^[:blank:]]\{1,\}/\1/' YourFile > Output.txt

1
sed 's/[^[:blank:]]*//5'
mikeserv

@mikeserv สิ่งนี้จะทำให้ทั้งสองตัวคั่นโดยรอบsed 's/[[:blank:]*[^[:blank:]]*//5'ดีกว่า จุดที่ดีมาก ฉันสงสัยว่า Sed ใช้ char แต่ละตัวในฐานะนิติบุคคล แต่มันมีรูปแบบที่ไม่แตกต่างที่ยิ่งใหญ่ที่สุดในฐานะเอนทิตี้ของมัน
NeronLeVelu

sed 's/[[:blank:]][^[:blank:]]*//4'จะลบฟิลด์ที่ 5 ทั้งหมด
mikeserv

@mikeserv สมมติว่ามีพื้นที่ไม่ได้เริ่มต้นในบรรทัด (เช่นในตัวอย่าง)
NeronLeVelu

ในกรณีนี้ใช่ฉันคิดว่าคุณพูดถูก โดยปกติสิ่งดังกล่าวจะเป็นโมฆะข้อมูลและพฤติกรรมจะถูกต้อง ในกรณีนี้คุณควรทำตามที่ @cuonglm ได้และให้แน่ใจว่าคุณอ้างอิงคำพูดทุกครั้งที่เหมือนsed 's/[[:blank:]][^[:blank:]][^[:blank:]]*//4'หรือ w / GNU / BSD / Toybox s:sed sed -E 's/[[:blank:]][^[:blank:]]+//4'
mikeserv



-1

ใช้ Perl> 5.10 (และประสบความสำเร็จในการแสดงผลทุกบรรทัด: 0)): -

perl -nE '/^((\w+ +){4})\w+ *(.*)/; say $1.$3' file
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.