คำสั่งด้านล่างอาจใช้เวลาหลายนาทีขึ้นอยู่กับขนาดไฟล์ มีวิธีอื่นอีกหรือไม่
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_file1 เลือกบรรทัดแรก
d ลบ
x บันทึกและปิด
นี่เป็นเพียงทฤษฎี แต่ ...
ระบบไฟล์ที่กำหนดเอง (ดำเนินการโดยใช้ FUSE หรือกลไกที่คล้ายกัน) สามารถเปิดเผยไดเรกทอรีที่มีเนื้อหาเหมือนกับไดเรกทอรีที่มีอยู่แล้วที่อื่น แต่มีไฟล์ที่ถูกตัดทอนตามที่คุณต้องการ ระบบไฟล์จะแปลไฟล์ออฟเซ็ตทั้งหมด จากนั้นคุณจะไม่ต้องเขียนไฟล์ใหม่เสียเวลา
แต่เนื่องจากความคิดนี้ไม่สำคัญมากเว้นแต่คุณจะมีไฟล์หลายสิบเทราไบต์การใช้ระบบไฟล์ดังกล่าวจะแพงเกินไป / ใช้เวลานานกว่าจะใช้งานได้จริง
tailผมค่อนข้างจะนับเวลาที่จะทำทั้งสองเอาบรรทัดแรกและแทนที่ด้วยbigfile.txtbigfile.new