Câu trả lời:
Lý do file.txt trống sau lệnh đó là thứ tự mà shell thực hiện. Điều đầu tiên xảy ra với dòng đó là chuyển hướng. Tệp "file.txt" được mở và cắt thành 0 byte. Sau đó, lệnh sed chạy, nhưng tại thời điểm đó tệp đã trống.
Có một vài lựa chọn, hầu hết liên quan đến việc ghi vào một tệp tạm thời.
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
lệnh sẽ là: printf "%s\n" 1d w q | ed file.txt
(I tim ed)
-exec sed -i '1d' {} \;
Một tùy chọn rất nhẹ khác chỉ là 'cắt đuôi' mọi thứ trừ dòng đầu tiên (đây có thể là một cách dễ dàng để loại bỏ các tiêu đề tệp nói chung):
# -n +2 : start at line 2 of the file.
tail -n +2 file.txt > file.stdout
Theo dõi @Evan Teitelman, bạn có thể:
tail -n +2 file.txt | sponge file.txt
Để tránh một tập tin tạm thời. Một lựa chọn khác có thể là:
echo "$(tail -n +2 file.txt)" > file.txt
Và kể từ đó trở đi. Kiểm tra lần cuối:
[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 ~]$
Rất tiếc, chúng tôi đã mất một dòng mới (mỗi bình luận @ 1_CR bên dưới), thay vào đó hãy thử:
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 ~]$
Quay trở lại với sed, thử:
printf '%s\n\n' "$(sed '1d' file.txt)" > file.txt
hoặc có lẽ
echo -e "$(sed '1d' file.txt)\n" > file.txt
Để tránh tác dụng phụ.
tail
thuật này hiệu quả với tôi (mất chưa đến 3 giây trên tệp 130mb). Cảm ơn!
echo "$(tail -n +2 file.txt)" > file.txt
là câu trả lời hoàn hảo.
Cũng hãy xem sponge
từ
moreutils
. sponge
ngâm dữ liệu từ đầu vào tiêu chuẩn cho đến khi kết thúc ghi của đầu vào tiêu chuẩn đóng trước khi ghi vào tệp. Nó được sử dụng như vậy:
sed '1d' file.txt | sponge file.txt
Chủ đề này được quan tâm, vì vậy tôi kiểm tra điểm chuẩn theo 3 cách:
sed '1d' d.txt > tmp.txt
tail -n +2 d.txt > tmp.txt
sed -i '1d' d.txt
Lưu ý rằng mục tiêu d.txt
là tệp 5,4 GB
Nhận kết quả:
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
Kết luận: Có vẻ như dưới đây là cách nhanh nhất:
sed '1d' file.txt > tmpfile; mv tmpfile file.txt
sed '1d' d.txt
Phương pháp của bạn không bao gồm (hoặc có vẻ như bằng cách đọc các bài kiểm tra của bạn) mv
lệnh. Trong các thử nghiệm của tôi trên FreeBSD với tệp 20 MB sed -i
là nhanh nhất.
ex
có thể được sử dụng để chỉnh sửa tại chỗ thực sự không liên quan đến tệp tạm thời
ex -c ':1d' -c ':wq' file.txt
strace -e open ex -c ':1d' -c ':wq' foo
. ex cắt ngắn tệp gốc bằng tệp tạm thời, trong đó tùy chọn GNU sed -i ghi đè lên bản gốc bằng tệp tạm thời. Tôi không chắc làm thế nào sed của BSD hoạt động.
Bạn có thể sử dụng Vim trong chế độ Ex:
ex -s -c '1d|x' file.txt
1
tìm dòng đầu tiên
d
xóa bỏ
x
lưu và đóng
Lệnh này sẽ xóa 1 dòng và lưu dưới dạng "file.txt".
sed '1d' file.txt > /tmp/file.txt && mv /tmp/file.txt file.txt || rm -f /tmp/file.txt
Để xóa một dòng praticiler trong tập tin
Tập tin '1d'
Tập tin '1d3d'
Xóa charecter trong dòng
1 Xóa hai điều lệ đầu tiên trong lin
Tập tin của Sed 's / ^ ..
2 Xóa hai dòng chrectercin cuối cùng
Tập tin của Sed 's / .. £ //'
3 Xóa dòng trống
Tập tin '/ ^ £ / d'
£
≠ $
.
Có thể sử dụng vim để làm điều này:
vim -u NONE +'1d' +wq! /tmp/test.txt
tập tin mèo01 | sed -e '1,3d'
// hiển thị nội dung trong tệp01 nhưng xóa dòng thứ nhất và thứ ba
sed
, bạn có thể sử dụngsed -i .bak '1d' file.txt
.