Sau đây sẽ in dòng khớp TERMINATE
cho đến cuối tập tin:
sed -n -e '/TERMINATE/,$p'
Giải thích: -n
vô hiệu hóa hành vi mặc định của sed
việc in từng dòng sau khi thực thi tập lệnh của nó trên tập lệnh đó, -e
chỉ ra một tập lệnh đến sed
, /TERMINATE/,$
là một lựa chọn phạm vi địa chỉ (dòng) có nghĩa là dòng đầu tiên khớp với TERMINATE
biểu thức chính quy (như grep) ở cuối tệp ( $
) và p
là lệnh in in dòng hiện tại.
Điều này sẽ in từ dòng theo dòng phù hợp TERMINATE
cho đến cuối tệp:
(từ SAU dòng phù hợp đến EOF, KHÔNG bao gồm dòng phù hợp)
sed -e '1,/TERMINATE/d'
Giải thích: 1,/TERMINATE/
là lựa chọn phạm vi địa chỉ (dòng) có nghĩa là dòng đầu tiên cho đầu vào của dòng thứ 1 khớp với TERMINATE
biểu thức chính quy và d
là lệnh xóa sẽ xóa dòng hiện tại và chuyển sang dòng tiếp theo. Vì sed
hành vi mặc định là in các dòng, nó sẽ in các dòng sau khi TERMINATE
kết thúc đầu vào.
Biên tập:
Nếu bạn muốn các dòng trước TERMINATE
:
sed -e '/TERMINATE/,$d'
Và nếu bạn muốn cả hai dòng trước và sau TERMINATE
trong 2 tệp khác nhau trong một lần chạy:
sed -e '1,/TERMINATE/w before
/TERMINATE/,$w after' file
Các tập tin trước và sau sẽ chứa dòng kết thúc, vì vậy để xử lý mỗi tập tin bạn cần sử dụng:
head -n -1 before
tail -n +2 after
Chỉnh sửa2:
NẾU bạn không muốn mã hóa tên tập tin trong tập lệnh sed, bạn có thể:
before=before.txt
after=after.txt
sed -e "1,/TERMINATE/w $before
/TERMINATE/,\$w $after" file
Nhưng sau đó, bạn phải thoát khỏi $
ý nghĩa của dòng cuối cùng để shell sẽ không cố gắng mở rộng $w
biến (lưu ý rằng bây giờ chúng ta sử dụng dấu ngoặc kép quanh tập lệnh thay vì dấu ngoặc đơn).
Tôi quên nói rằng dòng mới là quan trọng sau khi tên tệp trong kịch bản để sed biết rằng tên tệp kết thúc.
Chỉnh sửa: 2016-0530
Sébastien Clément hỏi: "Làm thế nào bạn sẽ thay thế mã hóa cứng TERMINATE
bằng một biến?"
Bạn sẽ tạo một biến cho văn bản phù hợp và sau đó thực hiện theo cách tương tự như ví dụ trước:
matchtext=TERMINATE
before=before.txt
after=after.txt
sed -e "1,/$matchtext/w $before
/$matchtext/,\$w $after" file
để sử dụng một biến cho văn bản phù hợp với các ví dụ trước:
## Print the line containing the matching text, till the end of the file:
## (from the matching line to EOF, including the matching line)
matchtext=TERMINATE
sed -n -e "/$matchtext/,\$p"
## Print from the line that follows the line containing the
## matching text, till the end of the file:
## (from AFTER the matching line to EOF, NOT including the matching line)
matchtext=TERMINATE
sed -e "1,/$matchtext/d"
## Print all the lines before the line containing the matching text:
## (from line-1 to BEFORE the matching line, NOT including the matching line)
matchtext=TERMINATE
sed -e "/$matchtext/,\$d"
Các điểm quan trọng về việc thay thế văn bản bằng các biến trong các trường hợp này là:
- Các biến (
$variablename
) được bao trong single quotes
[ '
] sẽ không "mở rộng" nhưng các biến bên trong double quotes
[ "
] sẽ. Vì vậy, bạn phải thay đổi tất cả các single quotes
để double quotes
nếu chúng chứa văn bản mà bạn muốn thay thế bằng một biến.
- Các
sed
phạm vi cũng chứa một $
và ngay lập tức được theo sau bởi một chữ cái như:$p
, $d
, $w
. Họ cũng sẽ giống như biến để được mở rộng, vì vậy bạn phải thoát khỏi những $
ký tự với một dấu chéo ngược [ \
] như: \$p
, \$d
, \$w
.
grep 'TERMINATE' file