Sed: Thay thế mô hình trên mỗi dòng mới thứ hai?


10

Có cách nào để nói sedđể thay thế mô hình trên mỗi lần xuất hiện thứ hai không? Hoặc ít nhất là trên mỗi dòng thứ hai? (Chắc chắn điều đó là có thể với một kịch bản, nhưng tôi đã tự hỏi mình liệu sedcó thể làm được không).

Biên tập

tôi đã tìm thấy

sed -e "s/pattern/replacement/g;n"

Nhưng nó thay thế mọi lần xuất hiện đầu tiên, không phải lần thứ hai.

Thí dụ

Tập tin đầu vào:

I have a pattern in each line
Also the second line has the pattern
Another pattern here
And -- you guess it -- a pattern

Sản phẩm chất lượng:

I have a pattern in each line
Also the second line has the replacement
Another pattern here
And -- you guess it -- a replacement

Câu trả lời:


6

xem /programming/5858200/sed-replace-every-nth-occurrence

Giải pháp sử dụng awk chứ không phải sed, nhưng "sử dụng công cụ phù hợp cho công việc". Nó có thể hoặc không thể thực hiện trong sed nhưng, ngay cả khi nó là, nó sẽ dễ dàng hơn rất nhiều trong một công cụ như awk hoặc perl.


1
Sử dụng những gì tôi đã học được ở đó tôi giúp người sed -e 'n;s/2004-2009/6e législature/g'giải quyết vấn đề của tôi.
Matthieu Riegler

1
sẽ không nhận được mỗi lần xuất hiện thứ hai , nó sẽ tìm kiếm mẫu của bạn trên mỗi dòng thứ hai . tức là bỏ qua các dòng 1, 3, 5, 7, v.v. Tất nhiên, điều đó vẫn có thể làm việc cho tài liệu cụ thể của bạn.
cas

Phải, tôi biết. đó là những gì tôi thực sự cần
Matthieu Riegler

14
sed 's/pattern/replacement/2'

Sẽ thay thế lần xuất hiện thứ hai trên mỗi dòng có mẫu.


nếu bạn có GNU sed:

sed '1~2N ; s/pattern/replacement/2'

Bắt đầu từ dòng một 1, dòng sau nó sẽ được thêm vào không gian mẫu Nsau đó slệnh sẽ thay thế lần xuất hiện thứ hai của mẫu. sau đó sedsẽ di chuyển hai dòng xuống ~2và lặp lại.


Tôi không muốn thứ hai nhưng mỗi giây.
Matthieu Riegler

Tôi có một mẫu trên mỗi dòng. Điều đó sẽ không làm việc.
Matthieu Riegler

sẽ rất vui khi biết điều đó trước đó. Vì vậy, mô hình xảy ra trên dòng một, hai, ba và bốn (vv) và bạn muốn thay thế mẫu trên dòng hai, bốn, v.v?
llua

một sự thay thế ngắn hơn có thể là code(sed '1 ~ 2s / mẫu / thay thế /')
jaap

2

Giải thích đơn giản:

Trên dòng đầu tiên có ít nhất một lần xuất hiện của MẪU bạn muốn bỏ qua nó và in dòng như hiện trạng. Trên dòng thứ hai có chứa ít nhất một lần xuất hiện của MẪU bạn muốn thay thế phiên bản đầu tiên của THỰC HÀNH bằng THAY THẾ. Trên dòng thứ ba có chứa ít nhất một lần xuất hiện của MẪU bạn muốn in dòng như hiện trạng. Trên dòng thứ tư có chứa ít nhất một lần xuất hiện của MẪU bạn muốn thay thế phiên bản đầu tiên của THỰC HÀNH bằng THAY THẾ. Và như thế. Các dòng không khớp với MẪU nên được in mà không thay đổi.

Điều này có thể dễ dàng thực hiện với Sed như vậy:

sed -e '/PATTERN/ { :inside' -e 'n;s//REPLACEMENT/;t' -e 'b inside' -e '}'

Hoặc, với ít khoảng trắng hơn và nhãn ngắn hơn:

sed -e '/PATTERN/{:i' -e 'n;s//REPLACEMENT/;t' -e 'b i' -e '}'

EDIT: Tôi chỉ đọc lại câu hỏi và phát hiện ra cách giải thích khó hơn:

Thay thế lần xuất hiện thứ hai của MẪU trong toàn bộ tài liệu bằng THAY THẾ, cho dù điều đó xảy ra trên cùng một dòng với lần xuất hiện đầu tiên hay không. Để lại lần xuất hiện đầu tiên và thứ ba không thay đổi. Vân vân.

Tôi tin rằng điều này cũng có thể được thực hiện với Sed, mặc dù nó RẤT NHIỀU và tôi tin rằng nó phụ thuộc vào biểu thức thông thường sẽ được sử dụng. Tôi sẽ cố gắng làm việc gì đó và đăng nó, nhưng bây giờ tôi sẽ để câu trả lời này với phiên bản đơn giản ở trên.


thay thế test của bạn bằng một quit và lấy đầu vào như thế, { sed '...'; cat; } <inputchỉ cho một sự thay thế duy nhất
mikeerv

1

Bạn đã rất gần, chỉ cần bỏ qua dòng đầu tiên:

sed '1n;s/pattern/replacement/;n'

Tại sao nên awklà công cụ tốt hơn trong trường hợp này?


0

Một mẫu biểu tượng trong một dòng: sed 's / (a ​​[^ a] *) a / \ 1c / g'

Mỗi mẫu thứ hai (chỉ một mẫu phù hợp trên mỗi dòng có thể xuất hiện. Nếu hai hoặc nhiều mẫu phù hợp trên một dòng sẽ xuất hiện, chỉ mẫu thứ hai sẽ được thay thế)

echo -e "test\nreplace_me\ntest\ntest\nreplace_me\nreplace_me\nreplace_me" | \
sed '/replace_me/{:a;N;/replace_me.*replace_me/!Ta;s/replace_me/replaced/2;}'
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.