Tìm kiếm một chuỗi và in mọi thứ trước và sau trong một phạm vi


9

Tôi có tập tin này:

sometext1{
string1
}

sometext2{
string2
string3
}

sometext3{
string4
string5
string6
}

Tôi muốn tìm kiếm tệp này cho một chuỗi cụ thể và in mọi thứ trước khi chuỗi này mở ra {và mọi thứ sau chuỗi này cho đến khi kết thúc }. Tôi đã cố gắng để đạt được điều này với sed nhưng nếu tôi cố gắng in mọi thứ trong phạm vi, /{/,/string2/ví dụ như sed in này:

sometext1{
string1
}

sometext2{
string2
sometext3{
string4
string5
string6
}

Nếu tôi tìm kiếm chuỗi "string2", tôi cần đầu ra là:

sometext2{
string2
string3
}

Cảm ơn.


Chà, bây giờ tôi thấy rằng tôi cần số dòng của ouput trong tệp gốc để xóa chúng sau này. Tôi đã thử thay đổi lệnh mà @mikeerv cung cấp không có may mắn, tôi hơi bối rối với chức năng giữ của sed.
Rodrigo

tốt, geez, Rodrigo, bạn đã không nói với ai đó ngoài chính bạn. nó có thể được thực hiện, nhưng nó được thực hiện tốt nhất như grep -n '' <infile | sed .... Các sedlệnh sẽ cần sửa đổi; cụ thể là các bit /địa chỉ /tìm kiếm ^các neo hàng đầu. Vì vậy, nếu bạn đang sử dụng câu trả lời của tôi, bạn có thể làm được : grep -n '' | sed 'H;/{$/h;/^[^:]*:}/x;/{\n.*PATTERN/!d'. Tất cả các dòng đầu ra sẽ được thêm tiền tố với số dòng của tệp gốc theo sau là dấu hai chấm 1:sometext1{\n2:string1và v.v. sedsẽ chỉ lọc những gì nó sẽ lọc trước đó, ngoại trừ mỗi dòng đầu ra mở bằng một số.
mikeerv

Câu trả lời:


9

Đây là hai lệnh. Nếu bạn muốn một lệnh cắt tới .*{$dòng cuối cùng trong một chuỗi (như @don_crissti làm với ed), bạn có thể thực hiện:

sed 'H;/{$/h;/^}/x;/{\n.*PATTERN/!d'

... Hoạt động bằng cách nối thêm mọi dòng vào Hkhông gian cũ theo \nký tự ewline, ghi đè lên hkhông gian cũ cho mỗi dòng khớp {$và hoán đổi hkhông gian cũ và mẫu cho mỗi dòng khớp ^}- và từ đó xóa bộ đệm của nó.

Nó chỉ in dòng mà phù hợp với một {sau đó một \newline và sau đó PATTERNtại một số điểm - và rằng chỉ có bao giờ xảy ra ngay sau khi một swap đệm.

{$phù hợp với bất kỳ dòng nào trong một loạt các trận đấu đến cuối cùng trong chuỗi, nhưng bạn có thể nhận được tất cả những dòng bao gồm như:

sed '/PATTERN.*\n/p;//g;/{$/,/^}/H;//x;D'

Những gì nó làm là hoán đổi mô hình và hkhông gian cũ cho mỗi ...{$.*^}.*chuỗi, nối tất cả các dòng trong chuỗi vào Hkhông gian cũ theo \nký tự Dewline và bỏ qua \nký tự ewline xuất hiện đầu tiên trong không gian mẫu cho mỗi chu kỳ dòng trước khi bắt đầu lại với những gì còn lại.

Tất nhiên, lần duy nhất nó nhận được \newline trong không gian mẫu là khi một dòng đầu vào khớp với ^}- kết thúc phạm vi của bạn - và do đó, khi nó chạy lại tập lệnh trong bất kỳ trường hợp nào khác, nó chỉ kéo theo dòng đầu vào tiếp theo thông thường.

Khi PATTERNđược tìm thấy trong không gian mô hình giống như một \newline, tuy nhiên, nó in lô trước khi ghi đè lên nó bằng ^}một lần nữa (vì vậy nó có thể kết thúc phạm vi và tuôn bộ đệm) .

Cho tệp đầu vào này (cảm ơn don) :

sometext1{
string1
}

sometext2{
PATTERN
string3
}

sometext3{
string4
string5
string6
}

Header{
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}
}

Bản in đầu tiên:

sometext2{
PATTERN
string3
}
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}

...va thu hai...

sometext2{
PATTERN
string3
}
Header{
sometext4{
some string

string unknown

here's PATTERN and PATTERN again
and PATTERN too
another string here
}

@don_crissti - Tôi không biết. Nó chỉ phân định trình tự cho một dòng bắt đầu bằng }. Điều này có thể có ích cho việc thích ... open{\nsub;\n{ command; }\n}; close- nhưng tôi không chắc đó là những gì đang diễn ra ở đây ...
mikeerv

Xin chào @mikeerv - Tôi có một câu hỏi tương tự được nêu ra ở đây unix.stackexchange.com/questions/232509/ , giải pháp của bạn hoạt động trên một tệp nhỏ, nhưng tôi có một tệp lớn và tôi đang nhận được "Giữ không gian bị tràn." thông báo lỗi. Bất cứ cơ hội nào bạn biết, làm thế nào tôi có thể giải quyết điều này? Rất cám ơn
Narayan Akhade

@NarayanAkhade - không. dù sao cũng không phải đại tu. trừ khi ... có những khoảng rộng lớn của đầu vào không được chứa trong {...}các khối không? Nếu đó là trường hợp và bạn đang sử dụng giải pháp đầu tiên thì bạn có thể làm /{$/,/^}/Hngay từ đầu thay vì chỉ H. Nhưng nếu bạn cũng đã thử giải pháp thứ hai mà vẫn gặp phải lỗi tương tự thì điều đó không có khả năng giúp đỡ vì giải pháp đó đã làm điều đó. Và cũng không giảm giá ed. don có một câu trả lời rất hay ở đây, và edcó thể được áp dụng để sử dụng các tệp bộ đệm tạm thời rất đơn giản, điều này sẽ ngăn chặn lỗi tràn bộ nhớ mem.
mikeerv

6

Đây là một giải pháp với ed:

ed -s filename <<< $'g/PATTERN/?{?,/}/p\nq\n'

đó là:

g/PATTERN/     # mark each line matching PATTERN  
?{?,/}/p       # for each marked line, print all lines from the previous { up to the next }  
q              # quit editor

Điều này giả sử chỉ có một dòng với PATTERNgiữa mỗi cặp { }nếu không bạn sẽ nhận được đầu ra trùng lặp cho mỗi dòng bổ sung PATTERNbên trong cùng một khối.
Nó sẽ hoạt động cho nhiều bộ { }chứa một dòng khớp, PATTERNví dụ: cho một tệp thử nghiệm với PATTERNhai phần khác nhau:

sometext1{
string1
}

sometext2{
PATTERN
string3
}

sometext3{
string4
string5
string6
}

Header{
sometext4{
some string

string unknown

here's PATTERN again

another string here
}
}

đang chạy

ed -s sample <<< $'g/PATTERN/?{?,/}/p\nq\n'

đầu ra:

sometext2{
PATTERN
string3
}
sometext4{
some string

string unknown

here's PATTERN again

another string here
}

Tôi đã lấy rất nhiều từ điều này, thực sự! Cảm ơn rất nhiều!
mikeerv

Tôi thậm chí không biết lệnh này tồn tại. Cảm ơn
Rodrigo

4

Với pcregrep:

pcregrep -M '(?s)\{[^}]*PATTERN.*?\}'

Hoặc với GNU grepđược cung cấp, đầu vào không chứa byte NUL:

grep -Poz '.*(?s)\{[^}]*PATTERN.*?\}'

0
$ awk 'BEGIN{RS="\n\n"; FS="[{}]"} {if ($2 ~ /string4/) {print $2}}' t1.txt
string4
string5
string6

Ở đâu:

  • string4 -> chuỗi được khớp
  • t1.txt -> chứa nội dung tệp được đề cập trong truy vấn

-2

tên tập tin sed -n '/ string / p'

-n khi được thêm vào sed hành vi mặc định của sed bị chặn, câu lệnh này có thể không cung cấp cho bạn chính xác những gì bạn muốn nhưng nó sẽ thay thế chuỗi

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.