sed: xóa tất cả các lần xuất hiện của một chuỗi trừ lần đầu tiên


14

Tôi có một logfile với dấu thời gian trong đó. Đôi khi có nhiều dấu thời gian trong một dòng. Bây giờ tôi muốn xóa tất cả các dấu thời gian khỏi một dòng nhưng giữ lại dấu đầu tiên.

Tôi có thể làm s/pattern//2nhưng điều đó chỉ loại bỏ sự xuất hiện thứ hai và sedkhông cho phép một cái gì đó như thế s/pattern//2-.

Bất kỳ đề xuất?


Tôi nên nói rằng đó là sed của busybox. Xin lỗi vì điều đó.
Dân gian van Heusden

Câu trả lời:


4

Với GNU sed:

sed 's/pattern//2g'

Các 2chỉ định rằng mẫu thứ hai và tất cả phần còn lại gsẽ loại bỏ. Vì vậy, điều này sẽ giữ cái đầu tiên.


1
Mà Cygwin có (một cổng, rõ ràng) và MacOS thì không. Achh! Giải pháp này thanh lịch hơn rất nhiều.
r_alex_hall

7

Điều này sẽ hoạt động (thay thế _ bằng một cái gì khác nếu nó xung đột với nhật ký của bạn):

sed -e 's/pattern/_&/1' -e 's/\([^_]\)pattern//g' -e 's/_\(pattern\)/\1/'

1
nếu bạn muốn một dấu phân cách duy nhất, hãy sử dụng \n.
mikeerv

5
sed -e ':begin;s/pattern//2;t begin'

hoặc không có sed goto:

sed -e 's/\(pattern\)/\1\n/;h;s/.*\n//;s/pattern//g;H;g;s/\n.*\n//'

Các giải pháp chung để loại bỏ khỏi vị trí thứ n (3 chẳng hạn) là:

sed -e ':begin;s/pattern//4;t begin'
sed -e 's/\(pattern\)/\1\n/;h;s/.*\n//3;s/pattern//g;H;g;s/\n.*\n//'

1

Một biến thể nhỏ trong câu trả lời của @ jillagre (được sửa đổi cho mạnh mẽ) có thể trông giống như:

sed 's/p\(attern\)/p\n\1/;s///g;s/\n//'

... nhưng trong một số seds, bạn có thể cần phải thay thế nở phía bên phải của s///tuyên bố ubst hiến đầu tiên bằng một ký tự \newline theo nghĩa đen .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.