นี่เป็นหัวข้อนอกเรื่อง แต่คุณสามารถใช้ได้
find -maxdepth 1 -type f -name '*.txt' | xargs python -c '
import fileinput
for line in fileinput.input(inplace=True):
print line.replace("blah", "blee"),
'
ประโยชน์หลักของที่นี่ (มากกว่า... xargs ... -I {} ... sed ...
) คือความเร็ว: คุณหลีกเลี่ยงการเรียกใช้sed
10 ล้านครั้ง มันจะเร็วขึ้นถ้าคุณหลีกเลี่ยงการใช้ Python (เนื่องจาก python ค่อนข้างช้า, ค่อนข้างมาก) ดังนั้น Perl อาจเป็นตัวเลือกที่ดีกว่าสำหรับงานนี้ ฉันไม่แน่ใจว่าจะทำสิ่งที่เทียบเท่ากับ Perl ได้อย่างสะดวก
วิธีการทำงานนี้คือการxargs
เรียก Python ที่มีอาร์กิวเมนต์มากที่สุดเท่าที่จะสามารถใส่ในบรรทัดคำสั่งเดียวและดำเนินการต่อไปจนกว่าจะหมดอาร์กิวเมนต์ (ซึ่งถูกจัดหาโดยls -f *.txt
) จำนวนข้อโต้แย้งสำหรับการเรียกใช้แต่ละครั้งจะขึ้นอยู่กับความยาวของชื่อไฟล์และอื่น ๆ อีกมากมาย fileinput.input
ฟังก์ชั่นอัตราผลตอบแทนต่อเนื่องสายจากไฟล์ที่มีชื่อในการขัดแย้งแต่ละภาวนาของและinplace
ตัวเลือกที่จะบอกว่ามันน่าอัศจรรย์ "จับ" การส่งออกและใช้มันเพื่อแทนที่แต่ละบรรทัด
โปรดทราบว่าreplace
วิธีสตริงของ Python ไม่ได้ใช้ regexps ถ้าคุณต้องการที่คุณต้องและการใช้งานimport re
print re.sub(line, "blah", "blee")
พวกเขาเป็น regexps Perl sed -r
เข้ากันได้ซึ่งมีการจัดเรียงของรุ่นปราการแน่นหนาของคนที่คุณได้รับด้วย
แก้ไข
ตามที่อากิระกล่าวถึงในความคิดเห็นเวอร์ชันดั้งเดิมที่ใช้ glob ( ls -f *.txt
) แทนที่find
คำสั่งจะไม่ทำงานเพราะเชลล์จะประมวลผลโดยเชลล์ ( bash
) เอง ซึ่งหมายความว่าก่อนที่คำสั่งจะทำงานแม้กระทั่งชื่อไฟล์ 10 ล้านชื่อจะถูกแทนที่ลงในบรรทัดคำสั่ง นี่ค่อนข้างรับประกันว่าจะเกินขนาดสูงสุดของรายการอาร์กิวเมนต์ของคำสั่ง คุณสามารถใช้xargs --show-limits
สำหรับข้อมูลเฉพาะระบบนี้
ขนาดสูงสุดของรายการอาร์กิวเมนต์จะถูกนำมาพิจารณาด้วยxargs
เช่นกันซึ่ง จำกัด จำนวนอาร์กิวเมนต์ที่ส่งผ่านไปยังการร้องขอของ python แต่ละครั้งตามข้อ จำกัด นั้น เนื่องจากxargs
ยังคงต้องเรียกใช้ไพ ธ อนสองสามครั้งคำแนะนำของอากิระที่จะใช้os.path.walk
ในการรับรายชื่อไฟล์อาจจะช่วยคุณได้บ้าง
sed
สำหรับแต่ละไฟล์ ฉันไม่แน่ใจว่ามีวิธีการเปิดแก้ไขบันทึกและปิดชุดไฟล์sed
หรือไม่ หากความเร็วเป็นสิ่งจำเป็นคุณอาจต้องการใช้โปรแกรมอื่นบางทีอาจเป็น Perl หรือ Python