sed
วิธีดี แต่ห่วงผ่านสายทั้งหมดไม่ได้ หากคุณทราบจำนวนบรรทัดที่คุณต้องการเก็บไว้ (เพื่อเป็นตัวอย่างฉันใช้ 99 ตรงนี้) คุณสามารถทำสิ่งนี้ได้:
sed -i '100,$ d' myfile.txt
คำอธิบาย: sed
เป็นตัวประมวลผลนิพจน์ทั่วไป ด้วยตัวเลือกที่-i
กำหนดมันประมวลผลไฟล์โดยตรง ("inline") - แทนที่จะอ่านมันและเขียนผลลัพธ์ไปยังเอาต์พุตมาตรฐาน 100,$
เพียงแค่หมายถึง "จากบรรทัด 100 ถึงท้ายไฟล์" - และตามด้วยคำสั่งd
ซึ่งคุณอาจเดาได้อย่างถูกต้องว่าจะ "ลบ" ดังนั้นในระยะสั้นคำสั่งหมายถึง: "ลบทุกบรรทัดจากบรรทัด 100 ไปยังจุดสิ้นสุดของไฟล์จาก myfile.txt" 100 คือบรรทัดแรกที่จะลบตามที่คุณต้องการเก็บ 99 บรรทัด
แก้ไข:หากมีไฟล์บันทึกที่คุณต้องการเก็บไว้เช่น100 บรรทัดสุดท้าย :
[ $(wc -l myfile.txt) -gt 100 ] && sed -i "1,$(($(wc -l myfile.txt|awk '{print $1}') - 100)) d" myfile.txt
เกิดขึ้นที่นี่คืออะไร:
[ $(wc -l myfile.txt) -gt 100 ]
: ทำสิ่งต่อไปนี้หากไฟล์มีมากกว่า 100 บรรทัด
$((100 - $(wc -l myfile.txt|awk '{print $1}')))
: คำนวณจำนวนบรรทัดที่จะลบ (เช่นทุกบรรทัดของไฟล์ยกเว้น (สุดท้าย) 100 เพื่อเก็บไว้)
1, $((..)) d
: ลบทุกบรรทัดจากบรรทัดแรกถึงบรรทัดที่คำนวณ
แก้ไข:เนื่องจากคำถามเพิ่งแก้ไขเพื่อให้รายละเอียดเพิ่มเติมฉันจะรวมข้อมูลเพิ่มเติมนี้ไว้ในคำตอบของฉันด้วย ข้อเท็จจริงที่เพิ่มเข้ามาคือ:
- ขนาดที่ระบุจะยังคงอยู่กับไฟล์ (10,000 ไบต์)
- แต่ละบรรทัดมีขนาดเฉพาะเป็นไบต์ (ตัวอย่างเช่น 300 ไบต์)
จากข้อมูลเหล่านี้มีความเป็นไปได้ที่จะคำนวณจำนวนบรรทัดที่จะยังคงเป็น "/" ซึ่งมีตัวอย่างหมายถึง 33 บรรทัด คำว่าเชลล์สำหรับการคำนวณ: $((size_to_remain / linesize))
(อย่างน้อยบน Linux ที่ใช้ Bash ผลลัพธ์จะเป็นจำนวนเต็ม) คำสั่งที่ปรับแล้วตอนนี้จะอ่าน:
# keep the start of the file (OPs question)
sed -i '34,$ d' myfile.txt
# keep the end of the file (my second example)
[ $(wc -l myfile.txt) -gt 33 ] && sed -i "1,33 d" myfile.txt
เนื่องจากขนาดเป็นที่รู้จักล่วงหน้าจึงไม่จำเป็นต้องมีการคำนวณที่ฝังอยู่ในsed
คำสั่งอีกต่อไป แต่เพื่อความยืดหยุ่นภายในเชลล์สคริปต์บางตัวสามารถใช้ตัวแปรได้
สำหรับการประมวลผลแบบมีเงื่อนไขขึ้นอยู่กับขนาดไฟล์หนึ่งสามารถใช้โครงสร้างต่อไปนี้ "ทดสอบ" - โครงสร้าง:
[ "$(ls -lk $file | awk ' {print $5}')" -gt 100 ] &&
ซึ่งหมายความว่า: "ถ้าขนาด$file
เกินกว่า 100kB ทำ ... " ( ls -lk
แสดงขนาดไฟล์เป็น kB ที่ตำแหน่ง 5 ดังนั้นawk
จะใช้เพื่อแยกข้อมูลนี้ออกมาอย่างแน่นอน)