ฉันจะลบบรรทัดแรกของไฟล์และเก็บการเปลี่ยนแปลงได้อย่างไร
ฉันลองมัน แต่มันจะลบเนื้อหาทั้งหมดของไฟล์
$sed 1d file.txt > file.txt
ฉันจะลบบรรทัดแรกของไฟล์และเก็บการเปลี่ยนแปลงได้อย่างไร
ฉันลองมัน แต่มันจะลบเนื้อหาทั้งหมดของไฟล์
$sed 1d file.txt > file.txt
คำตอบ:
เหตุผล file.txt ว่างเปล่าหลังจากคำสั่งนั้นเป็นลำดับที่เชลล์ทำสิ่งต่าง ๆ สิ่งแรกที่เกิดขึ้นกับบรรทัดนั้นคือการเปลี่ยนเส้นทาง ไฟล์ "file.txt" ถูกเปิดและตัดเป็น 0 ไบต์ หลังจากนั้นคำสั่ง sed จะทำงาน แต่ ณ จุดนี้ไฟล์จะว่างเปล่า
มีตัวเลือกน้อยส่วนใหญ่เกี่ยวข้องกับการเขียนไปยังไฟล์ชั่วคราว
sed '1d' file.txt > tmpfile; mv tmpfile file.txt # POSIX
sed -i '1d' file.txt # GNU sed only, creates a temporary file
perl -ip -e '$_ = undef if $. == 1' file.txt # also creates a temporary file
ed
อาจใช้โปรแกรมแก้ไขข้อความเช่น
ed
คำสั่งจะเป็น: printf "%s\n" 1d w q | ed file.txt
(ฉันหัวใจเอ็ด)
-exec sed -i '1d' {} \;
ตัวเลือกอื่นที่มีน้ำหนักเบามากเป็นเพียง 'หาง' ทุกอย่าง แต่บรรทัดแรก (นี่อาจเป็นวิธีที่ง่ายในการลบส่วนหัวของไฟล์โดยทั่วไป):
# -n +2 : start at line 2 of the file.
tail -n +2 file.txt > file.stdout
การติดตาม @Evan Teitelman คุณสามารถ:
tail -n +2 file.txt | sponge file.txt
เพื่อหลีกเลี่ยงไฟล์ชั่วคราว ตัวเลือกอื่นอาจจะ:
echo "$(tail -n +2 file.txt)" > file.txt
และอื่น ๆ ทดสอบล่าสุด:
[user@work ~]$ cat file.txt
line 1
line 2
line 3
line 4
line 5
[user@work ~]$ echo "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 2
line 3
line 4
line 5
[user@work ~]$
อุ๊ปส์เราทำ newline หาย (ต่อความคิดเห็น @ 1_CR ด้านล่าง) ลองแทน:
printf "%s\n\n" "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 1
line 2
line 3
line 4
line 5
[user@work ~]$ printf '%s\n\n' "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 2
line 3
line 4
line 5
[user@work ~]$
กลับมาเฉยๆลอง:
printf '%s\n\n' "$(sed '1d' file.txt)" > file.txt
หรือบางที
echo -e "$(sed '1d' file.txt)\n" > file.txt
เพื่อหลีกเลี่ยงผลข้างเคียง
tail
เคล็ดลับทำงานให้ฉัน (ใช้เวลาน้อยกว่า 3 วินาทีในไฟล์ 130MB ก) ขอบคุณ!
echo "$(tail -n +2 file.txt)" > file.txt
เป็นคำตอบที่สมบูรณ์แบบ
นอกจากนี้ยังจะดูที่มาจากsponge
ดูดซับข้อมูลจากอินพุตมาตรฐานจนกระทั่งสิ้นสุดการเขียนของอินพุตมาตรฐานปิดก่อนเขียนลงในไฟล์ มันถูกใช้อย่างนั้น:moreutils
sponge
sed '1d' file.txt | sponge file.txt
หัวข้อนี้เป็นเรื่องที่น่าสนใจดังนั้นฉันจะทดสอบเกณฑ์มาตรฐานใน 3 วิธี:
sed '1d' d.txt > tmp.txt
tail -n +2 d.txt > tmp.txt
sed -i '1d' d.txt
โปรดทราบว่าเป้าหมายd.txt
คือไฟล์ 5.4GB
รับผล:
run 1 : sed '1d' d.txt > r1.txt
14s
run 2 : tail -n +2 d.txt > r2.txt
20s
run 3 : sed -i '1d' d.txt
88s
สรุป: ดูเหมือนว่าด้านล่างเป็นวิธีที่เร็วที่สุด:
sed '1d' file.txt > tmpfile; mv tmpfile file.txt
sed '1d' d.txt
วิธีการของคุณไม่ได้รวม (หรือดังนั้นดูเหมือนว่าโดยการอ่านการทดสอบของคุณ) mv
คำสั่ง ในการทดสอบของฉันใน FreeBSD ด้วยไฟล์ขนาด 20MB sed -i
นั้นเร็วที่สุด
ex
สามารถใช้สำหรับการแก้ไขในสถานที่จริงที่ไม่เกี่ยวข้องกับไฟล์ชั่วคราว
ex -c ':1d' -c ':wq' file.txt
strace -e open ex -c ':1d' -c ':wq' foo
. ex ตัดทอนไฟล์ต้นฉบับด้วยไฟล์ temp โดยที่ตัวเลือก GNU sed's -i จะเขียนทับไฟล์ต้นฉบับด้วยไฟล์ temp ฉันไม่แน่ใจว่าการทำงานของ BSD เป็นอย่างไร
วิธีที่สั้นและง่ายที่สุดในการลบบรรทัดแรกจากไฟล์ที่ใช้sed
คือ:
$ sed -i -n -e '2,$p' file.txt
คุณสามารถใช้ Vim ในโหมด Ex:
ex -s -c '1d|x' file.txt
1
ค้นหาบรรทัดแรก
d
ลบ
x
บันทึกและปิด
คำสั่งนี้จะลบ 1 บรรทัดและบันทึกเป็น "file.txt"
sed '1d' file.txt > /tmp/file.txt && mv /tmp/file.txt file.txt || rm -f /tmp/file.txt
ในการลบบรรทัด praticiler ในไฟล์
Sed 'ไฟล์ 1d'
แก้ไขไฟล์ '1d3d'
ลบ charecter ในบรรทัด
1 ลบกฎบัตรสองข้อแรกใน lin
ไฟล์ของ /^..// 'ของ Sed
2 ลบบรรทัด chrectercin สองอันสุดท้าย
ไฟล์ 's / .. £ //'
3 ลบบรรทัดว่าง
จัดเก็บไฟล์ '/ ^ £ / d'
£
$
สามารถใช้กลุ่มเพื่อทำสิ่งนี้:
vim -u NONE +'1d' +wq! /tmp/test.txt
cat file01 | sed -e '1,3d'
// แสดงเนื้อหาใน file01 แต่ลบบรรทัดแรกและบรรทัดที่สาม
sed
sed -i .bak '1d' file.txt