ฉันจะลบบรรทัดที่แน่นอน (โดยใช้หมายเลขบรรทัด) ในไฟล์ได้อย่างไร


27

มีบรรทัดเฉพาะที่ฉันต้องการลบออกจากไฟล์ สมมุติว่ามันเป็นบรรทัดที่ 20-37 แล้วก็บรรทัดที่ 45 ฉันจะทำอย่างไรโดยไม่ระบุเนื้อหาของบรรทัดเหล่านั้น


ไฟล์ของคุณใหญ่แค่ไหน? สามารถโหลดเข้าไปในหน่วยความจำได้ไหม?
Faheem Mitha

ไม่กี่กิโลไบต์
tshepang

คำตอบ:


29

ด้วยsedเช่น:

sed '20,37d; 45d' < input.txt > output.txt

หากคุณต้องการทำสิ่งนี้แทน:

sed --in-place '20,37d; 45d' file.txt

มีวิธีทำในสถานที่หรือไม่?
tshepang

ฉันแนะนำไฟล์ sed -i
enzotib

1
@Tshepang: ใช้edหรือ GNU sed -iหรือspongeหรือวิธีการไฟล์ขนาดใหญ่
Gilles 'หยุดความชั่วร้าย'

3
ฉันมักจะสงสัยเกี่ยวกับคำอาจจะทำให้เข้าใจผิดในสถานที่ , เมื่อพูดถึง 'sed' ดังนั้นผมมองมันได้ใน 'คน sed': --in สถาน [= SUFFIX] This option specifies that files are to be edited in-place. GNU sed' ไม่นี้โดยการสร้างแฟ้มชั่วคราว และส่งออกไปยังไฟล์นี้แทนที่จะส่งออกมาตรฐาน `... ฉันไม่รู้เกี่ยวกับ 'sed' อื่นใด แต่การส่งกำลังของการอัพเดต" แบบ "พร้อมกับตัวแก้ไขสตรีมไม่" คำนวณ ":)
Peter.O

2
วิธีการ "แบบแทนที่" ส่วนใหญ่ใช้ไฟล์ชั่วคราวในประสบการณ์ของฉัน
Faheem Mitha

5

edถ้าเหมาะกับไฟล์สบายในหน่วยความจำคุณยังสามารถใช้
คำสั่งนั้นค่อนข้างคล้ายกับคำสั่งsedด้านบนที่มีความแตกต่างที่น่าสังเกต : คุณจะต้องผ่านรายการหมายเลขบรรทัด / ช่วงที่จะลบตามลำดับจากมากไปน้อย (จากบรรทัดสูงสุดไม่มี / ช่วงถึงต่ำสุด) เหตุผลก็คือเมื่อคุณลบ / แทรก / แยก / รวมกับบรรทัดedบัฟเฟอร์ข้อความจะถูกปรับปรุงหลังจากแต่ละคำสั่งย่อยดังนั้นหากคุณลบบางบรรทัดส่วนที่เหลือของบรรทัดต่อไปนี้จะไม่อยู่ในตำแหน่งเดียวกันในบัฟเฟอร์เมื่อ คำสั่งย่อยถัดไปถูกเรียกใช้งาน ดังนั้นคุณต้องเริ่มต้นย้อนหลัง1 การแก้ไข
ในสถานที่ :

ed -s in_file <<IN
45d
20,37d
w
q
IN

หรือ

ed -s in_file <<< $'45d\n20,37d\nw\nq\n'

หรือ

printf '%s\n' 45d 20,37d w q | ed -s in_file

แทนที่write ด้วย,print หากคุณต้องการพิมพ์ผลลัพธ์ที่ได้แทนที่จะเขียนลงไฟล์ หากคุณต้องการเก็บไฟล์ดั้งเดิมไว้และเขียนไปยังไฟล์อื่นคุณสามารถส่งชื่อไฟล์ใหม่ไปยังคำwสั่งย่อย rite:

ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN

1 ยกเว้นว่าคุณยินดีที่จะคำนวณหมายเลขบรรทัดใหม่หลังจากแต่ละdelete ซึ่งค่อนข้างเล็กน้อยสำหรับกรณีนี้โดยเฉพาะ (หลังจากลบบรรทัด 20-37 เช่น 18 บรรทัดบรรทัด 18 กลายเป็นบรรทัดที่ 27) ดังนั้นคุณสามารถเรียกใช้:

ed -s in_file <<IN
20,37d
27d
w
q
IN

อย่างไรก็ตามหากคุณต้องลบหมายเลข / ช่วงหลายบรรทัดการย้อนกลับเป็นเรื่องที่ไม่ต้องคิดมาก


เป็นqคำสั่งที่มีประโยชน์ที่สิ้นสุดหรือไม่ ฉันเดาว่ามันจะออกทางใดทางหนึ่ง
Tom Fenech

@TomFenech - การใช้งานบางอย่างไม่ออกจากทางใดทางหนึ่ง (แต่ส่วนใหญ่ทำ ... ฉันไม่สามารถหาหัวข้อที่มีการกล่าวถึง ... )
don_crissti

1

แค่อ่านมันเข้าไปในหน่วยความจำเปลี่ยนมันแล้วเขียนมันกลับมา คุณสามารถทำสิ่งที่ชอบ

filename = "foo"
f = open(filename, 'r+')                                                                                                                                 
linenums = [1, 3]                                                                                                                                            
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]                                                                                                                                          
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()

ทดสอบกับไฟล์ 5 บรรทัด เครดิตไปที่http://pleac.sourceforge.net/pleac_python/fileaccess.htmlดูที่ส่วน "การแก้ไขไฟล์โดยไม่ต้องมีไฟล์ชั่วคราว" ดูเพิ่มเติมที่https://stackoverflow.com/questions/125703/how-do-i-modify-a-text-file-in-python

หมายเหตุบางส่วน:

  1. หนึ่งสามารถตัดทอนไฟล์ก่อนจากนั้นเขียนไปที่มันแทนที่จะเขียนแล้วตัดทอนตามที่กล่าวไว้ข้างต้น อย่างไรก็ตามฉันไม่ทราบถึงการตั้งค่า Python ที่อนุญาตให้อ่านและทำการเขียนที่ถูกตัดทอน แต่บางทีฉันอาจจะพลาดบางสิ่งบางอย่างเนื่องจากเอกสารไม่ชัดเจน ซึ่งพาฉันไป

  2. บางครั้งเอกสาร Python ดูดจริงๆ ดู http://docs.python.org/library/functions.html#open

    โหมด 'r +', 'w +' และ 'a +' เปิดไฟล์สำหรับการอัปเดต (โปรดทราบว่า 'w +' จะตัดทอนไฟล์)

    สิ่งนี้มีความหมายกับคุณหรือไม่? อะไรคือ "เปิดรับการอัปเดต"

  3. ฉันไม่ทราบว่าการทำเช่นนี้ในหลามตรงข้ามกับบางสิ่งที่ไม่เหมือนกันอย่างเช่นโปรแกรมแก้ไขสตรีม มันอาจจะพกพาได้มากกว่า แต่ฉันไม่รู้ว่าพกพาสะดวกอย่างไร ฉันเพิ่งเขียนแบบนั้นเพราะฉันรู้สึกสะดวกสบายกับการเขียนโปรแกรมระดับต่ำกว่าการใช้เครื่องมือ unix แบบคลาสสิกซึ่งดีถ้าพวกเขาทำสิ่งที่คุณต้องการอย่างแน่นอน แต่ (ฉันคิดว่า) โดยทั่วไปมีความยืดหยุ่นน้อยกว่า

  4. วิธีนี้ (จัดการไฟล์ในหน่วยความจำ) ทำการซื้อขายหน่วยความจำสำหรับพื้นที่ดิสก์ ควรทำงานบนเครื่องที่มีหน่วยความจำไม่กี่ Gb สำหรับไฟล์ที่มีขนาดไม่เกินร้อย Mb Python ไม่สามารถจัดการกับสายอักขระได้อย่างมีประสิทธิภาพดังนั้นการเปลี่ยนเป็น C / C ++ จะเพิ่มประสิทธิภาพเล็กน้อยและลดการใช้หน่วยความจำอย่างมาก


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.