Tôi muốn xóa một hoặc nhiều số dòng cụ thể khỏi một tệp. Làm thế nào tôi có thể làm điều này bằng cách sử dụng sed?
Tôi muốn xóa một hoặc nhiều số dòng cụ thể khỏi một tệp. Làm thế nào tôi có thể làm điều này bằng cách sử dụng sed?
Câu trả lời:
Nếu bạn muốn xóa các dòng 5 đến 10 và 12:
sed -e '5,10d;12d' file
Điều này sẽ in kết quả ra màn hình. Nếu bạn muốn lưu kết quả vào cùng một tệp:
sed -i.bak -e '5,10d;12d' file
Điều này sẽ sao lưu tệp lên đến file.bak
và xóa các dòng đã cho.
Lưu ý: Số dòng bắt đầu từ 1. Dòng đầu tiên của tệp là 1, không phải 0.
sed -e '5,$d' file
sed -e '5d' file
. Cú pháp là <address><command>
; trong đó <address>
có thể là một dòng giống như 5
hoặc một phạm vi dòng như thế 5,10
, và lệnh d
xóa dòng hoặc dòng đã cho. Các địa chỉ cũng có thể là biểu thức chính quy hoặc ký hiệu đô la $
cho biết dòng cuối cùng của tệp.
Bạn có thể xóa một dòng đơn cụ thể với số dòng của nó bằng cách
sed -i '33d' file
Thao tác này sẽ xóa dòng trên số dòng 33 và lưu tệp đã cập nhật.
sed -i '0,/<TARGET>/{/<NEW_VALUE>/d;}' '<SOME_FILE_NAME>'
. Cảm ơn!
và awk là tốt
awk 'NR!~/^(5|10|25)$/' file
$ cat foo
1
2
3
4
5
$ sed -e '2d;4d' foo
1
3
5
$
Đây thường là một triệu chứng của một antipotype. Công cụ tạo ra các số dòng cũng có thể được thay thế bằng một công cụ xóa các dòng ngay lập tức. Ví dụ;
grep -nh error logfile | cut -d: -f1 | deletelines logfile
(nơi mà deletelines
tiện ích bạn đang tưởng tượng bạn cần) cũng giống như
grep -v error logfile
Phải nói rằng, nếu bạn đang ở trong một tình huống mà bạn thực sự cần phải thực hiện nhiệm vụ này, bạn có thể tạo một sed
tập lệnh đơn giản từ tệp số dòng. Hài hước (nhưng có lẽ hơi khó hiểu) bạn có thể làm điều này với sed
.
sed 's%$%d%' linenumbers
Điều này chấp nhận một tệp số dòng, mỗi dòng trên một dòng và tạo ra, trên đầu ra tiêu chuẩn, cùng một số dòng được d
nối sau mỗi dòng. Đây là một sed
tập lệnh hợp lệ , mà chúng ta có thể lưu vào một tệp hoặc (trên một số nền tảng) sang một sed
thể hiện khác :
sed 's%$%d%' linenumbers | sed -f - logfile
Trên một số nền tảng, sed -f
không hiểu đối số tùy chọn -
có nghĩa là đầu vào tiêu chuẩn, do đó bạn phải chuyển hướng tập lệnh sang tệp tạm thời và dọn sạch nó khi bạn hoàn thành hoặc có thể thay thế dấu gạch ngang bằng /dev/stdin
hoặc/proc/$pid/fd/1
nếu hệ điều hành của bạn (hoặc trình bao ) có cái đó.
Như mọi khi, bạn có thể thêm -i
trước -f
tùy chọn để sed
chỉnh sửa tệp đích, thay vì tạo kết quả trên đầu ra tiêu chuẩn. Trên các nền tảng * BSDish (bao gồm cả OSX), bạn cũng cần cung cấp một đối số rõ ràng -i
; một thành ngữ phổ biến là cung cấp một đối số trống; -i ''
.
p
thay vì d
cùng với tùy chọn -n
(nó sẽ không hoạt động mà không hoạt động -n
và !d
cũng không hoạt động).
Tôi muốn đề xuất một khái quát với awk.
Khi tệp được tạo bởi các khối có kích thước cố định và các dòng cần xóa được lặp lại cho mỗi khối, awk có thể hoạt động tốt theo cách như vậy
awk '{nl=((NR-1)%2000)+1; if ( (nl<714) || ((nl>1025)&&(nl<1029)) ) print $0}'
OriginFile.dat > MyOutputCuttedFile.dat
Trong ví dụ này, kích thước của khối là 2000 và tôi muốn in các dòng [1..713] và [1026..1029].
NR
là biến được sử dụng bởi awk để lưu trữ số dòng hiện tại.%
đưa ra phần còn lại (hoặc mô đun) của phép chia hai số nguyên;nl=((NR-1)%BLOCKSIZE)+1
Ở đây chúng ta viết vào biến nl số dòng bên trong khối hiện tại. (xem bên dưới)||
và &&
là toán tử logic OR và AND .print $0
viết dòng đầy đủWhy ((NR-1)%BLOCKSIZE)+1:
(NR-1) We need a shift of one because 1%3=1, 2%3=2, but 3%3=0.
+1 We add again 1 because we want to restore the desired order.
+-----+------+----------+------------+
| NR | NR%3 | (NR-1)%3 | (NR-1)%3+1 |
+-----+------+----------+------------+
| 1 | 1 | 0 | 1 |
| 2 | 2 | 1 | 2 |
| 3 | 0 | 2 | 3 |
| 4 | 1 | 0 | 1 |
+-----+------+----------+------------+