Làm thế nào để grep dòng, dựa trên một mẫu nhất định?


8

Giả sử tôi có một tệp chứa hai dòng sau:

2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
2014-05-05      09:12:17    /aa/bbbb/cccccc?dddddddd    16767 

Tôi chỉ cần lấy dòng chứa mẫu /aa/bbbb/cccccc, tôi không cần dòng thứ hai chứa các ký tự phụ ?dddddddd. Bây giờ khi tôi đã cố gắng

grep '/aa/bbbb/cccccc' file

Sau đó, cả hai dòng được chọn. Tôi cần dòng đầy đủ để grep -okhông thể là một giải pháp.

Điều gì có thể là giải pháp khả thi khi sử dụng grep để chỉ dòng đầu tiên được chọn dựa trên mẫu tìm kiếm?

Câu trả lời:


7

Hãy thử lệnh grep dưới đây sử dụng tham số -P( Perl-regapi ).

grep -P '(?<!\S)/aa/bbbb/cccccc(?!\S)' file
  • (?<!\S)Cái nhìn tiêu cực này khẳng định rằng ký tự đứng trước chuỗi /aa/bbbb/ccccccsẽ là bất kỳ nhưng không phải là ký tự không phải khoảng trắng .

  • (?!\S) Cái nhìn tiêu cực khẳng định rằng nhân vật theo dõi trận đấu sẽ là bất kỳ nhưng không phải là một nhân vật không phải không gian.

Một grep khác,

 grep -E '(^|\s)/aa/bbbb/cccccc(\s|$)' file

Qua trăn,

script.py

#!/usr/bin/python3
import re
import sys
file = sys.argv[1]
with open(file, 'r') as f:
    for line in f:
        for i in line.split():
            if i == "/aa/bbbb/cccccc":
                print(line, end='')

Lưu mã trên trong một tập tin và đặt tên là script.py. Sau đó thực hiện đoạn script trên bằng cách

python3 script.py /path/to/the/file/you/want/to/work/with

Cảm ơn người đàn ông. Btw điều này có thể được thực hiện bằng cách sử dụng regex bình thường / mở rộng thay vì regl perl không?
heemayl

1
giống như terdon đã đăng, bạn có thể chỉ cầngrep '/aa/bbbb/cccccc ' file
Avinash Raj

Nhưng ở trên sẽ không in các dòng chỉ có /aa/bbbb/ccccccchuỗi.
Avinash Raj

Bạn cũng có thể kết hợp điều đó vớigrep -E '/aa/bbbb/cccccc(\s+|$)' file
terdon

vâng, như thế nàygrep -E '(^|\s)/aa/bbbb/cccccc(\s|$)' file
Avinash Raj

10

Cách đơn giản nhất là thêm một khoảng trắng sau mẫu của bạn:

$ grep '/aa/bbbb/cccccc ' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Hoặc, để phù hợp với tất cả các loại khoảng trắng:

$ grep  '/aa/bbbb/cccccc[[:space:]]' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Hoặc là

$ grep -P '/aa/bbbb/cccccc\s+' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Hoặc, với một cái nhìn tích cực :

$ grep -P '/aa/bbbb/cccccc(?=\s)' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Hoặc, với một cái nhìn tiêu cực :

$ grep -P '/aa/bbbb/cccccc(?!\S)' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Hoặc bạn có thể đảo ngược trận đấu:

$ grep  -v 'c?' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Hoặc, để khớp với các dòng không chứa gì ngoài mẫu của bạn (không có khoảng trắng ở cuối):

grep -P '/aa/bbbb/cccccc(\s+|$)' file 
grep -E '/aa/bbbb/cccccc(\s+|$)' file 

Hoặc, bạn chỉ có thể sử dụng một tập lệnh nhỏ:

  • Trong awk:

    $ awk '$3=="/aa/bbbb/cccccc"' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    

    Hoặc, nếu bạn không biết mô hình của mình thuộc lĩnh vực nào

    $ awk '{for(i=1;i<=NF;i++){if($i=="/aa/bbbb/cccccc"){print}}}' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    
  • Ở Perl

    $ perl -ane 'print if grep {$_ eq "/aa/bbbb/cccccc"} @F' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    

@terdon tại grep -v 'c?' filesao bạn không sử dụng grep -v '?' filevì tệp chỉ có hai dòng trong đó.
αғsнιη

@KasiyA đúng, tôi chỉ muốn giữ một chút mô hình. Bạn hoàn toàn đúng, trong trường hợp cụ thể này, grep -v '?'sẽ là đủ.
terdon

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.