ฉันมีไฟล์ข้อความ 25GB ที่ต้องการสตริงแทนที่ในไม่กี่บรรทัด ฉันสามารถใช้งานได้sed
สำเร็จ แต่ใช้เวลาในการรันนานมาก
sed -i 's|old text|new text|g' gigantic_file.sql
มีวิธีที่เร็วกว่าในการทำเช่นนี้?
ฉันมีไฟล์ข้อความ 25GB ที่ต้องการสตริงแทนที่ในไม่กี่บรรทัด ฉันสามารถใช้งานได้sed
สำเร็จ แต่ใช้เวลาในการรันนานมาก
sed -i 's|old text|new text|g' gigantic_file.sql
มีวิธีที่เร็วกว่าในการทำเช่นนี้?
คำตอบ:
คุณสามารถลอง:
sed -i '/old text/ s//new text/g' gigantic_file.sql
จากการอ้างอิงนี้:
การเพิ่มประสิทธิภาพความเร็ว: หากต้องการเพิ่มความเร็วในการเรียกใช้งาน (เนื่องจากไฟล์อินพุตขนาดใหญ่หรือตัวประมวลผลช้าหรือฮาร์ดดิสก์) การทดแทนจะถูกดำเนินการอย่างรวดเร็วยิ่งขึ้นหากระบุนิพจน์ "ค้นหา" ไว้ก่อนที่จะกำหนด "s /.../" ../" คำแนะนำ.
นี่คือการเปรียบเทียบไฟล์ 10G ก่อน:
$ time sed -i 's/original/ketan/g' wiki10gb
real 5m14.823s
user 1m42.732s
sys 1m51.123s
หลังจาก:
$ time sed -i '/ketan/ s//original/g' wiki10gb
real 4m33.141s
user 1m20.940s
sys 1m44.451s
sed
คือสะกดผิด ฉันแก้ไขโพสต์เมื่อวานนี้ในการแก้ไขปัญหาที่ผ่านมาsed
คำสั่งที่ควรจะเป็นและไม่ได้time sed -i '/original/ s//ketan/g' wiki10gb
time sed -i '/ketan/ s//original/g' wiki10gb
ฉันคืนค่าการแก้ไขของฉันในวันนี้เพราะ 1. เวลาไม่ตรงกับคำสั่งและ 2. ฉันได้ทำการทดสอบเดียวกันกับ GNU บนไฟล์ 3+ GB และฉันไม่สังเกตเห็นความแตกต่างระหว่างสองsed
ทางเลือก ฉันสงสัยว่าความแตกต่างในบางครั้งเกิดจากการสะกดคำผิด
time
ผลลัพธ์เป็นการส่วนตัว แต่โดยรวมแล้วไม่มีความแตกต่างในเวลา
คำตอบสั้น ๆ คือ "ไม่" - ปัจจัย จำกัด ของคุณในการดำเนินการเช่นนี้คือดิสก์ IO ไม่มีวิธีใดที่จะสตรีมดิสก์ 25GB เร็วขึ้น คุณอาจได้รับการปรับปรุงเล็กน้อยหากคุณไม่แก้ไขในสถานที่และเขียนผลลัพธ์ของsed
ไดรฟ์แยกต่างหาก (ถ้าคุณมีหนึ่งที่มีอยู่) - เนื่องจากวิธีที่คุณสามารถอ่านจากที่หนึ่งในขณะที่เขียนไปยังอีกและมีเล็กน้อย ความขัดแย้งน้อยลงเป็นผล
คุณอาจจะสามารถเพิ่มความเร็วขึ้นเล็กน้อยโดยไม่ใช้เครื่องมือ regex สำหรับแต่ละบรรทัด - ดังนั้นสำหรับตัวอย่างการใช้ Perl (ผมค่อนข้างมั่นใจว่าคุณสามารถทำเช่นนี้กับsed
แต่ผมไม่ทราบว่าไวยากรณ์) - นี้จะเริ่มต้นจาก สาย 10,000 เป็นต้นไป
perl -pe '$. > 10_000 && s/old_text/new_text/g'
และถ้ามีการจัดเรียงของภาวะแทรกซ้อนใด ๆ ในเรื่องนี้ (metacharacters) แล้วลดการเหล่านั้นจะเล็กน้อยในการปรับปรุงประสิทธิภาพของเครื่องยนต์ regex ไม่
sed -i '10000,$ s/old_text/new_text/g'
sed
เปรียบเทียบอย่างไร- ฉันถือว่าเร็วกว่าเล็กน้อย แต่ไม่มากเพราะขนาดไฟล์
sed
ในperl
แต่หลังยังช่วยให้คุณเขียนมากขึ้น verbose สคริปต์เกินไป
หากข้อความใหม่และเก่ามีความยาวเท่ากันคุณสามารถค้นหาไฟล์และเขียนเฉพาะไบต์ที่มีการเปลี่ยนแปลงแทนการคัดลอกไฟล์ทั้งหมด ไม่เช่นนั้นคุณจะติดกับการย้ายข้อมูลจำนวนมาก
หมายเหตุ: นี่เป็นเรื่องยุ่งยากและเกี่ยวข้องกับการเขียนรหัสที่กำหนดเอง
ดู man page สำหรับ fseek หากคุณทำงานใน C หรือ C ++ หรือภาษาที่คุณโปรดปรานสำหรับการค้นหาและเขียนการโทรของระบบ
หากคุณยืนยันในการใช้บรรทัดคำสั่งเท่านั้นและคุณสามารถรับค่าออฟเซ็ตของข้อความได้คุณสามารถเขียนข้อความแทนที่ด้วยคำสั่ง "dd" ที่เขียนอย่างระมัดระวัง