Tôi cần trợ giúp với Grep để bắt đầu tại một phần


8

Tôi có một số tệp văn bản mà tôi muốn grep một phần mã từ đó. Mục tiêu tôi đang cố gắng đạt được là bắt đầu chế độ xem tại một dòng nhất định và sau đó có thể đọc bất cứ điều gì bên dưới nó. Ví dụ. Trong văn bản dưới đây, làm cách nào để tôi xem tệp văn bản tại điểm bắt đầu màu vàng. Tôi muốn xem nội dung của "màu vàng" cũng như mọi thứ bên dưới nó, bất kể nội dung đó là gì.

green
blue
cyan
magenta
purple
brown
yellow
red
orange
more orange
more blue
this is enough

Câu trả lời:


9

Sử dụng AWKAWK - đó là cách đơn giản nhất có thể nhận được:

awk '/yellow/,0' textfile.txt

Chạy mẫu

$ awk '/yellow/,0' textfile.txt                                
yellow
red
orange
more orange
more blue
this is enough

Grep

Bạn cũng có thể sử dụng grepvới --after-contexttùy chọn, để in số lượng dòng nhất định sau trận đấu

grep 'yellow' --after-context=999999  textfile.txt

Để tự động thiết lập bối cảnh, bạn có thể sử dụng $(wc -l textfile.txt). Ý tưởng cơ bản là nếu bạn có một dòng đầu tiên là một trận đấu và bạn muốn in mọi thứ sau trận đấu đó, bạn sẽ cần biết số dòng trong tệp trừ 1. May mắn thay, --after-contextsẽ không ném lỗi về số lượng các dòng, vì vậy bạn có thể cung cấp cho nó số hoàn toàn ngoài phạm vi, nhưng trong trường hợp bạn không biết nó, tổng số dòng sẽ làm

$ grep 'yellow' --after-context=$(wc -l < textfile.txt) textfile.txt
yellow
red
orange
more orange
more blue
this is enough

Nếu bạn muốn rút ngắn lệnh --after-contextlà tùy chọn tương tự -A$(wc -l textfile.txt), sẽ mở rộng thành số dòng theo sau là tên tệp. Vì vậy, cách bạn gõ textfile.txtchỉ một lần

grep "yellow" -A $(wc -l textfile.txt)

Con trăn

skolodya@ubuntu:$ ./printAfter.py textfile.txt                                 
yellow
red
orange
more orange
more blue
this is enough

DIR:/xieerqi
skolodya@ubuntu:$ cat ./printAfter.py                                          
#!/usr/bin/env python
import sys

printable=False
with open(sys.argv[1]) as f:
     for line in f:
        if "yellow" in line:
           printable=True
        if printable:
           print line.rstrip('\n')

Hoặc thay thế mà không có printablecờ

#!/usr/bin/env python
import sys

with open(sys.argv[1]) as f:
     for line in f:
        if "yellow" in line:
          for lines in f: # will print remaining lines
             print lines.rstrip('\n')
          exit()

Bạn có thể đơn giản hóa greplệnh để grep "yellow" -A $(wc -l textfile.txt).
Chỉ huy Byte

@ByteCommander yup, cũng có thể được thực hiện. Chỉ cần sử dụng tùy chọn đầy đủ cho sự rõ ràng
Sergiy Kolodyazhnyy

1
@ByteCommander Thật là một hack đáng yêu. Thật không may, nó chỉ hoạt động vì không có khoảng trắng trong tên tệp.
kasperd

@kasperd Ồ vâng, bạn nói đúng. Trong trường hợp đó, bạn sẽ phải quay trở lại mệnh lệnh ban đầu của Serg grep "yellow" -A $(wc -l < "my colors.txt") "my colors.txt".
Chỉ huy Byte

5

Bạn có thể làm điều đó bằng cách:

awk '/yellow/{f=1}f' file

trong đó "tệp" là tên tệp chứa văn bản của bạn.


Những bộ óc vĩ đại nghĩ giống nhau> :)
Sergiy Kolodyazhnyy

5

Không grep, nhưng sử dụng sed:

sed -n '/^yellow$/,$p' file
  • -n: ức chế in
  • /^yellow$/,$: phạm vi địa chỉ đi từ lần xuất hiện đầu tiên của một dòng khớp chính xác yellowđến bao gồm dòng cuối cùng
  • p: in các dòng trong phạm vi địa chỉ
% sed -n '/^yellow$/,$p' file
yellow
red
orange
more orange
more blue
this is enough

5

Đi dự tiệc muộn :)

Sử dụng grep:

grep -Pzo '(?s)\n\Kyellow\n.*' file.txt
  • -P cho phép chúng tôi sử dụng Regex tương thích Perl

  • -z làm cho tệp đầu vào được phân tách bằng ASCII NUL, thay vào đó là dòng mới

  • -o chỉ mất phần mong muốn

  • (?s)là công cụ sửa đổi DOTALL, cho phép chúng tôi khớp dòng mới bằng cách sử dụng mã thông báo .(bất kỳ ký tự nào)

  • Trong \n\K, \nkhớp với một dòng mới, \Kloại bỏ trận đấu

  • yellow\n.*các trận đấu được yellowtheo sau bởi một dòng mới và mọi thứ sau đó cũng được chọn và hiển thị trong đầu ra.

Thí dụ:

% grep -Pzo '(?s)\n\Kyellow\n.*' file.txt
yellow
red
orange
more orange
more blue
this is enough

Sử dụng ít python:

#!/usr/bin/env python2
with open('file.txt') as f:
    lines = f.readlines()
    print ''.join(lines[lines.index('yellow\n'):])
  • lines là danh sách chứa tất cả các dòng của tệp (cũng có dòng mới theo dõi)

  • lines.index('yellow\n')cung cấp cho chúng tôi chỉ số thấp nhất của linesnơi yellow\nđược tìm thấy

  • lines[lines.index('yellow\n'):]sẽ sử dụng danh sách cắt để lấy phần bắt đầu từ đầu yellow\nđến cuối

  • join sẽ nối các phần tử của danh sách để xuất thành một chuỗi


Đẹp, nhưng bạn nên đề cập rằng mã Python chỉ tìm thấy toàn bộ các dòng bằng "màu vàng", nó không phát hiện ra các dòng như "nhiều màu vàng hơn".
Chỉ huy Byte

@ByteCommander Từ ví dụ của OP tôi nghĩ rõ ràng rằng họ muốn khớp chỉ yellowtrong dòng..cũng nếu đó không phải là trường hợp thì chúng ta cần thay đổi pythonalgo của mình ..
heemayl

Ừ chắc chắn. Dù sao đó cũng không phải là chỉ trích, chỉ là một gợi ý để cải thiện câu trả lời. Một số người khác đọc điều này có thể cho rằng mã hoạt động như thế nào grepvà không chỉ khớp với các dòng đầy đủ. Tôi nâng cấp btw.
Chỉ huy Byte

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.