มีบรรทัดเฉพาะที่ฉันต้องการลบออกจากไฟล์ สมมุติว่ามันเป็นบรรทัดที่ 20-37 แล้วก็บรรทัดที่ 45 ฉันจะทำอย่างไรโดยไม่ระบุเนื้อหาของบรรทัดเหล่านั้น
มีบรรทัดเฉพาะที่ฉันต้องการลบออกจากไฟล์ สมมุติว่ามันเป็นบรรทัดที่ 20-37 แล้วก็บรรทัดที่ 45 ฉันจะทำอย่างไรโดยไม่ระบุเนื้อหาของบรรทัดเหล่านั้น
คำตอบ:
ด้วยsed
เช่น:
sed '20,37d; 45d' < input.txt > output.txt
หากคุณต้องการทำสิ่งนี้แทน:
sed --in-place '20,37d; 45d' file.txt
This option specifies that files are to be edited in-place. GNU
sed' ไม่นี้โดยการสร้างแฟ้มชั่วคราว และส่งออกไปยังไฟล์นี้แทนที่จะส่งออกมาตรฐาน `... ฉันไม่รู้เกี่ยวกับ 'sed' อื่นใด แต่การส่งกำลังของการอัพเดต" แบบ "พร้อมกับตัวแก้ไขสตรีมไม่" คำนวณ ":)
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
แทนที่w
rite ด้วย,p
rint หากคุณต้องการพิมพ์ผลลัพธ์ที่ได้แทนที่จะเขียนลงไฟล์ หากคุณต้องการเก็บไฟล์ดั้งเดิมไว้และเขียนไปยังไฟล์อื่นคุณสามารถส่งชื่อไฟล์ใหม่ไปยังคำw
สั่งย่อย rite:
ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN
1
ยกเว้นว่าคุณยินดีที่จะคำนวณหมายเลขบรรทัดใหม่หลังจากแต่ละd
elete ซึ่งค่อนข้างเล็กน้อยสำหรับกรณีนี้โดยเฉพาะ (หลังจากลบบรรทัด 20-37 เช่น 18 บรรทัดบรรทัด 18 กลายเป็นบรรทัดที่ 27) ดังนั้นคุณสามารถเรียกใช้:
ed -s in_file <<IN
20,37d
27d
w
q
IN
อย่างไรก็ตามหากคุณต้องลบหมายเลข / ช่วงหลายบรรทัดการย้อนกลับเป็นเรื่องที่ไม่ต้องคิดมาก
q
คำสั่งที่มีประโยชน์ที่สิ้นสุดหรือไม่ ฉันเดาว่ามันจะออกทางใดทางหนึ่ง
แค่อ่านมันเข้าไปในหน่วยความจำเปลี่ยนมันแล้วเขียนมันกลับมา คุณสามารถทำสิ่งที่ชอบ
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
หมายเหตุบางส่วน:
หนึ่งสามารถตัดทอนไฟล์ก่อนจากนั้นเขียนไปที่มันแทนที่จะเขียนแล้วตัดทอนตามที่กล่าวไว้ข้างต้น อย่างไรก็ตามฉันไม่ทราบถึงการตั้งค่า Python ที่อนุญาตให้อ่านและทำการเขียนที่ถูกตัดทอน แต่บางทีฉันอาจจะพลาดบางสิ่งบางอย่างเนื่องจากเอกสารไม่ชัดเจน ซึ่งพาฉันไป
บางครั้งเอกสาร Python ดูดจริงๆ ดู http://docs.python.org/library/functions.html#open
โหมด 'r +', 'w +' และ 'a +' เปิดไฟล์สำหรับการอัปเดต (โปรดทราบว่า 'w +' จะตัดทอนไฟล์)
สิ่งนี้มีความหมายกับคุณหรือไม่? อะไรคือ "เปิดรับการอัปเดต"
ฉันไม่ทราบว่าการทำเช่นนี้ในหลามตรงข้ามกับบางสิ่งที่ไม่เหมือนกันอย่างเช่นโปรแกรมแก้ไขสตรีม มันอาจจะพกพาได้มากกว่า แต่ฉันไม่รู้ว่าพกพาสะดวกอย่างไร ฉันเพิ่งเขียนแบบนั้นเพราะฉันรู้สึกสะดวกสบายกับการเขียนโปรแกรมระดับต่ำกว่าการใช้เครื่องมือ unix แบบคลาสสิกซึ่งดีถ้าพวกเขาทำสิ่งที่คุณต้องการอย่างแน่นอน แต่ (ฉันคิดว่า) โดยทั่วไปมีความยืดหยุ่นน้อยกว่า
วิธีนี้ (จัดการไฟล์ในหน่วยความจำ) ทำการซื้อขายหน่วยความจำสำหรับพื้นที่ดิสก์ ควรทำงานบนเครื่องที่มีหน่วยความจำไม่กี่ Gb สำหรับไฟล์ที่มีขนาดไม่เกินร้อย Mb Python ไม่สามารถจัดการกับสายอักขระได้อย่างมีประสิทธิภาพดังนั้นการเปลี่ยนเป็น C / C ++ จะเพิ่มประสิทธิภาพเล็กน้อยและลดการใช้หน่วยความจำอย่างมาก
คุณสามารถใช้ Vim ในโหมด Ex:
ex -sc '20,37d|45d|x' file
d
ลบ
x
บันทึกและปิด