Mô hình đa dòng Grep


13

Làm cách nào để tìm kiếm một cụm từ trên nhiều dòng? Ví dụ: Cho phép có cụm từ "trà đá của tôi" thì nó có thể được gói trong các tệp văn bản:

as js skdfh dfh djh sf my
ice tea.

grep sẽ không khớp vì có một dòng mới ở giữa. Làm thế nào để tôi phù hợp với những người? Một mô hình đa dòng khác sẽ làpattern1_\n_pattern2

Tôi biết cách dễ nhất mà tôi làm ATM chỉ là grep cho một phần, ví dụ như chỉ băng với cờ -A2 -B2 và sau đó trong đầu ra đó, ví dụ như trà. Nhưng điều này rất tẻ nhạt. Vì vậy, tôi đang xen vào làm thế nào để bạn giải quyết điều này.


1
trang web chéo có thể trùng lặp của: stackoverflow.com/questions/152708/ từ
Ciro Santilli 改造 心 心

Câu trả lời:


16

Bạn có thể cài đặt pcregrep(có sẵn trong hầu hết các kho phân phối) - đó là grep sử dụng thư viện pcre , trong đó có "Biểu thức chính quy tương thích Perl". Nó có một tùy chọn dòng lệnh -Mcho phép bạn thực hiện tìm kiếm nhiều dòng - từ trang man :

"Đầu ra cho bất kỳ một trận đấu nào có thể bao gồm nhiều hơn một dòng."

Vì vậy, bạn có thể làm

pcregrep -M 'my\s+ice\s+tea' filename

Các \slà khoảng trắng, mà sẽ phù hợp \n\rtrong chế độ multiline, ngoài các ký tự khoảng trắng bình thường. Bạn cũng có thể kết hợp trực tiếp với ký tự dòng mới, vì vậy bạn có thể làm

pcregrep -M 'pattern1_\n_pattern2' filename

+1 đẹp. không bao giờ nghe nói về nó, nhưng đã thử nó và nó hoạt động như một bùa mê!
DaveParillo

Không grep -Elàm mô hình pcre?
Daenyth

3
@Daenyth grep -E chủ yếu chỉ có nghĩa là bạn có thể sử dụng ?, +, {, |, (, và )như ý nghĩa regex thông thường của họ mà không cần phải có một \ ở phía trước, khi bạn làm gì nếu bạn sử dụng grep chuẩn. Như vậy grep 'hello\s\+world' filelà tương đương với grep -E 'hello\s+world' file. Nó không làm PCRE. Có grep -Pcác biểu thức chính quy perl, nhưng nó là thử nghiệm (theo trang nam) và tôi nghĩ nó hơi khác so với pcregrep ...
Hamish Downer

1
Vâng, tôi đã nghĩ đến -Pkhi tôi nói -E, nhưng tôi không nhận ra nó khác.
Daenyth

3

Tôi có lẽ sẽ thực hiện tìm kiếm sử dụng vimcủa :vimgreplệnh. Điều này hoạt động theo cách tương tự mơ hồ grepnhưng hỗ trợ các vim RE và đường dẫn.

Về cơ bản, bạn chạy một cái gì đó như :vimgrep 'pattern1\npattern2' path/**cho một tìm kiếm đệ quy, sau đó nhập :copenđể hiển thị một cửa sổ nhỏ hơn chứa danh sách các kết quả khớp.

vimCác RE có thể làm hầu hết mọi thứ mà PCRE có thể, nhưng chúng phát triển tách biệt với dòng biểu thức chính quy perl nên hầu hết các công cụ nâng cao hoạt động khác nhau. Chức năng cơ bản của chúng giống với các RE cơ bản, nhưng chúng có một số bổ sung tiện lợi mà PCRE không cung cấp.

Tôi không chắc liệu có thể lấy :vimgrepra dữ liệu hay grepkhông; Tôi chỉ từng cố gắng sử dụng nó để điều hướng trong vim.

:help vimgreptừ bên trong vimđể biết thêm; :help pattern.txtđể biết thông tin về vimREs; để biết thêm thông tin về các đường dẫn xem :help wildcards.


Hãy cẩn thận - điều đó không hoàn toàn di động vì nó sẽ hoạt động khác nhau trên các nền tảng khác nhau
Daenyth

1
@Daenyth: bạn có nghĩa là dưới ảnh hưởng của khác nhau .vimrc? Nó nên dễ mang theo hơn so grepvới hệ điều hành: vimkhông có "hương vị POSIX" và hoạt động ít nhiều giống hệt ngay cả trong Windows. .................................................. ........................... Mặc dù có thể thêm vòng loại để đảm bảo rằng ví dụ: lượng "ma thuật" phù hợp sẽ được sử dụng trên RE, mặc dù theo tôi hiểu, có một quy tắc bất thành văn nghiêm ngặt để bỏ lựa chọn đó một mình.
trực giác

Tôi đã không sử dụng nó cho mình, nhưng chắc chắn nó sử dụng một phụ trợ khác trên các cửa sổ ( find.exethay vì grep). Có một câu hỏi khác trong vài tuần qua có vấn đề đó.
Daenyth

1
@Daenyth: Bạn đang nghĩ đến :vimgrephay :grep? Từ :help grep: "Ưu điểm của grep nội bộ [tức là :vimgrep] là nó hoạt động trên tất cả các hệ thống và sử dụng các mẫu tìm kiếm Vim mạnh mẽ."
trực giác

1
Ah, đó phải là nó. Tôi nhận được hai nhầm lẫn.
Daenyth

2

Grep chỉ hoạt động trên một dòng tại một thời điểm, nhưng bạn có thể sử dụng awk để in các dòng khớp với một loạt các mẫu:

cat file | awk '/foo/,/bar/'

nó sẽ phù hợp với bất cứ điều gì, không chỉ là dòng mới giữa hai mẫu


0

Để tận dụng tối đa unix, bạn cần tận dụng các đường ống. Bạn có thể làm điều này trong đơn giản bằng grepcách sử dụng ống (không cần tee):

$ grep -A1 "pattern1" file.txt |  grep "pattern2"

Mà tôi sẽ không xem xét tẻ nhạt.


Tôi nghĩ rằng đây là lỗi dễ xảy ra, vì giữa mẫu1 và mẫu2 có thể tồn tại mẫu3 có thể không phải là thứ bạn đang tìm kiếm. Vì vậy, bạn phải kiểm soát từng cú đánh bằng tay.
toán
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.