Phần 1
Đơn giản chỉ cần d
xóa dòng thứ 13:
sed '13d' <file.txt
Và một cách chung để làm phần bổ sung ở trên là:
sed '13!d' <file.txt
Phần 2
Bởi vì nó có thể được thực hiện:
sed -n ':a;${P;q};N;4,$D;ba' <file.txt
Lưu ý 4
là nhiều hơn số bạn yêu cầu. Vì vậy, nếu bạn muốn dòng thứ 10 cuối cùng, điều này sẽ là 11
.
Kiểm tra với seq
:
$ seq 100 | sed -n ':a;${P;q};N;4,$D;ba'
98
$
Cố gắng giải thích
:a # define label a
${ # match the last line
P # print the first line of the pattern space
q # quit
}
N # match all lines: append the next line to the pattern
4,${ # match the range of lines 4 to the end of the file
D # delete the first line of the pattern space
}
ba # match all lines: jump back to label a
Bổ sung có giá trị của Glenn Jackman:
Đó là "chỉ dòng thứ N". Đây là "tất cả NHƯNG dòng thứ N":
sed -n ':a;${s/^[^\n]*\n//;p;q};N;4,${P;D};ba'
hoạt động với GNU sed, \n
chuỗi có thể không hoạt động với các sed khác.
Tôi đã thử điều này với BSD sed (OSX) và thấy nó không hoạt động tốt ở dạng trên. Các vấn đề dường như là:
;
Được sử dụng để phân tách các dòng dường như thường hoạt động, nhưng không hoạt động sau một nhãn
- BSD sed dường như yêu cầu
;
sau lệnh cuối cùng trong {}
nhóm lệnh một dòng , trong khi GNU sed thì không
\n
nói chung có thể được sử dụng trong biểu thức chính quy, nhưng dường như không nằm trong []
biểu thức ngoặc. Vì vậy, để loại trừ các dòng mới, chúng ta có thể sử dụng một cái gì đó như [[:alnum:][:punct:][:graph:][:blank:]]
thay vào đó, mặc dù điều này có thể loại trừ các ký tự khác (cụ thể là các ký tự điều khiển khác).
Vì vậy, đây là một nỗ lực tại một phiên bản độc lập với nhiều nền tảng hơn:
sed -n ':a
${s/^[[:alnum:][:punct:][:graph:][:blank:]]*\n//p;q;};N;4,${P;D;};ba'
Điều này dường như hoạt động theo OSX và Ubuntu.
head
/tail
giải pháp chậm hơn nhiều so vớised
giải pháp. Cảm ơn mặc dù.