คำสั่งด้านล่างอาจใช้เวลาหลายนาทีขึ้นอยู่กับขนาดไฟล์ มีวิธีอื่นอีกหรือไม่
sed -i 1d large_file
คำสั่งด้านล่างอาจใช้เวลาหลายนาทีขึ้นอยู่กับขนาดไฟล์ มีวิธีอื่นอีกหรือไม่
sed -i 1d large_file
คำตอบ:
ลองed
แทน:
ed <<< $'1d\nwq' large_file
หากที่“ใหญ่” หมายถึงประมาณ 10 tail
ล้านเส้นหรือมากกว่าใช้ดีกว่า ไม่สามารถแก้ไขในสถานที่ได้ แต่ประสิทธิภาพของมันทำให้การขาดนั้นไม่สามารถให้อภัยได้:
tail -n +2 large_file > large_file.new
แก้ไขเพื่อแสดงความแตกต่างของเวลา:
( awk
เพิ่มรหัสโดย Jaypal ให้มีเวลาดำเนินการในเครื่องเดียวกัน (CPU 2.2GHz))
bash-4.2$ seq 1000000 > bigfile.txt # further file creations skipped
bash-4.2$ time sed -i 1d bigfile.txt
time 0m4.318s
bash-4.2$ time ed -s <<< $'1d\nwq' bigfile.txt
time 0m0.533s
bash-4.2$ time perl -pi -e 'undef$_ if$.==1' bigfile.txt
time 0m0.626s
bash-4.2$ time { tail -n +2 bigfile.txt > bigfile.new && mv -f bigfile.new bigfile.txt; }
time 0m0.034s
bash-4.2$ time { awk 'NR>1 {print}' bigfile.txt > newfile.txt && mv -f newfile.txt bigfile.txt; }
time 0m0.328s
awk
และได้ผลลัพธ์ต่อไปนี้ -[jaypal:~/Temp] seq 1000000 > bigfile.txt [jaypal:~/Temp] time awk 'NR>1 {print}' bigfile.txt >newfile.txt real 0m0.649s user 0m0.601s sys 0m0.033s
awk
ผลการดำเนินงานที่จะได้ใกล้ชิดกับsed
's (หมายเหตุสำหรับตัวเอง: ไม่เคยคาดหวัง - ทดสอบแทน)
tail -n +2 bigfile.txt > bigfile.new && mv -f bigfile.new bigfile.txt;
ฉันใช้ไฟล์เดียวกับล็อคเพื่อติดตามรายการงานเดียวที่ใช้โดยหลายกระบวนการ ฉันเริ่มด้วยการใช้โปสเตอร์เริ่มต้น: sed -i 1d large_file
. นั่นเป็นสาเหตุให้ไฟล์ล็อคเป็นเวลา 1-2 วินาที tail/mv
เสร็จสมบูรณ์คำสั่งผสมเกือบจะทันที ขอขอบคุณ!
ไม่มีวิธีที่จะลบสิ่งต่าง ๆ ได้อย่างมีประสิทธิภาพตั้งแต่เริ่มต้นไฟล์ การลบข้อมูลจากจุดเริ่มต้นต้องเขียนไฟล์ใหม่ทั้งหมด
การตัดออกจากจุดสิ้นสุดของไฟล์สามารถทำได้อย่างรวดเร็วมาก (ระบบปฏิบัติการจะต้องปรับข้อมูลขนาดไฟล์ซึ่งอาจเป็นการล้างบล็อคที่ไม่ได้ใช้ตอนนี้) โดยทั่วไปไม่สามารถทำได้เมื่อคุณพยายามลบออกจากส่วนหัวของไฟล์
ในทางทฤษฎีอาจเป็น "เร็ว" ถ้าคุณลบทั้งบล็อก / ขอบเขตอย่างแน่นอน แต่ไม่มีการเรียกระบบสำหรับสิ่งนั้นดังนั้นคุณต้องพึ่งพาความหมายเฉพาะของระบบไฟล์ (ถ้ามีอยู่) (หรือมีรูปแบบของการชดเชยภายในบล็อก / ขอบเขตแรกเพื่อทำเครื่องหมายจุดเริ่มต้นที่แท้จริงของไฟล์ฉันเดาไม่เคยได้ยินมาก่อนเช่นกัน)
วิธีที่มีประสิทธิภาพที่สุดอย่าทำ! หากคุณทำเช่นนั้นคุณต้องใช้พื้นที่ 'ใหญ่' สองเท่าในดิสก์และคุณเสีย IOs
หากคุณติดอยู่กับไฟล์ขนาดใหญ่ที่คุณต้องการอ่านโดยไม่มีบรรทัดที่ 1 ให้รอจนกว่าคุณจะต้องอ่านไฟล์นั้นเพื่อลบบรรทัดที่ 1 หากคุณต้องการส่งไฟล์จาก stdin ไปยังโปรแกรมให้ใช้ tail เพื่อทำ:
tail -n +2 | your_program
เมื่อคุณต้องการอ่านไฟล์คุณสามารถใช้โอกาสในการลบบรรทัดที่ 1 แต่ถ้าคุณมีพื้นที่ที่ต้องการบนดิสก์:
tail -n +2 | tee large_file2 | your_program
หากคุณไม่สามารถอ่านจาก stdin ให้ใช้ Fifo:
mkfifo large_file_wo_1st_line
tail -n +2 large_file > large_file_wo_1st_line&
your_program -i large_file_wo_1st_line
ดียิ่งขึ้นถ้าคุณใช้ทุบตีใช้ประโยชน์จากการทดแทนกระบวนการ:
your_program -i <(tail -n +2 large_file)
หากคุณต้องการค้นหาไฟล์ฉันไม่เห็นทางออกที่ดีไปกว่าการไม่ติดกับไฟล์ในตอนแรก หากไฟล์นี้ถูกสร้างโดย stdout:
large_file_generator | tail -n +2 > large_file
มิฉะนั้นจะมีวิธีแก้ปัญหาการแทนที่ Fifo หรือกระบวนการเสมอ:
mkfifo large_file_with_1st_file
large_file_generator -o large_file_with_1st_file&
tail -n +2 large_file_with_1st_file > large_file_wo_1st_file
large_file_generator -o >(tail -n 2+ > large_file_wo_1st_file)
คุณสามารถใช้ Vim ในโหมด Ex:
ex -sc '1d|x' large_file
1
เลือกบรรทัดแรก
d
ลบ
x
บันทึกและปิด
นี่เป็นเพียงทฤษฎี แต่ ...
ระบบไฟล์ที่กำหนดเอง (ดำเนินการโดยใช้ FUSE หรือกลไกที่คล้ายกัน) สามารถเปิดเผยไดเรกทอรีที่มีเนื้อหาเหมือนกับไดเรกทอรีที่มีอยู่แล้วที่อื่น แต่มีไฟล์ที่ถูกตัดทอนตามที่คุณต้องการ ระบบไฟล์จะแปลไฟล์ออฟเซ็ตทั้งหมด จากนั้นคุณจะไม่ต้องเขียนไฟล์ใหม่เสียเวลา
แต่เนื่องจากความคิดนี้ไม่สำคัญมากเว้นแต่คุณจะมีไฟล์หลายสิบเทราไบต์การใช้ระบบไฟล์ดังกล่าวจะแพงเกินไป / ใช้เวลานานกว่าจะใช้งานได้จริง
tail
ผมค่อนข้างจะนับเวลาที่จะทำทั้งสองเอาบรรทัดแรกและแทนที่ด้วยbigfile.txt
bigfile.new