Linux - Nhật ký grep từ một số dòng nhất định đến cuối tập tin


6

Tôi có một tệp văn bản tương tự như thế này:

line 1
line 2A
line 3
line 4A
line 5

Tôi muốn "grep" từ "dòng 2A" đến cuối tập tin, đại loại như thế này

cat file.txt|some_grep "line 2A"

Ngoài ra, tôi muốn "grep" từ "dòng 2A" sang dòng tiếp theo có chứa "A", đại loại như thế này

cat file.txt| some_grep "A"

Tôi muốn điều này để in ra:

line 2A
line 3
line 4A

Lệnh nào có thể giúp tôi đạt được điều này?


Đầu tiên là trường hợp chính xác là tầm thường đối với các mẫu phạm vi awk awk '/line 2A/,0'và trường hợp thứ hai có thể awk '/line 2A/,/A/&&!/line 2A/'hoặc nếu đó là ít nhất một char trước Aawk '/line 2A/,/[^2]A/'
dave_thedom_085

Cảm ơn bạn, nếu bạn có thể biến câu trả lời này thành câu trả lời, tôi sẽ đánh dấu nó là ... câu trả lời.
phong

Câu trả lời:


2

(mở rộng từ bình luận)

awkcó khả năng chọn 'phạm vi' các dòng phù hợp hoàn hảo với nhu cầu này, như được mô tả trong hướng dẫn sử dụng GNU-awk (gawk) . (Tính năng này hoạt động trong các awks khác nhưng gawkhướng dẫn sử dụng rất dễ liên kết.)

awk '/line 2A/,0'in các dòng bắt đầu bằng dòng đầu tiên khớp line 2Avà tiếp tục cho đến khi kết thúc đầu vào vì đây 0là điều kiện không bao giờ đúng.

awk '/line 2A/,/A/&&!/line 2A/'bắt đầu in với một dòng khớp line 2Avà dừng sau một dòng khớp Anhưng KHÔNG line 2A(và do đó không thể là cùng một dòng với dòng bắt đầu). Nó sẽ bắt đầu lại vào lần tiếp theo line 2A và cứ thế; nếu bạn muốn ngăn chặn rằng có những cách phức tạp hơn một chút để làm như vậy.

Nếu các dòng dừng luôn có một số ký tự khác 2trước, thì dòng Anày có thể được đơn giản hóa để awk '/line 2A/,/[^2]A/'dừng sau một dòng khớp với bất kỳ ký tự nào ngoài 2, theo sau là A. Bạn có thể muốn một biến thể của điều này, ví dụ như dừng trên bất kỳ một đơn vị nào chữ số-A khác với 2A, nhưng không khác Như WHAT; cho rằng điều kiện dừng có thể là ,/line [013-9]A/.


5

Tôi muốn "grep" từ "dòng 2A" đến cuối tệp:

sed -n '/2A/,$p'
  • -n: chặn sedđầu ra mặc định
  • / 2A /: dòng đầu ra từ dòng đầu tiên chứa "2A"
  • $: đến cuối tập tin

Tôi muốn "grep" từ "dòng 2A" sang dòng tiếp theo có chứa "A":

sed -n '/2A/,/A/p'
  • / A /: đầu ra cho đến khi một dòng chứa "A"

Tôi muốn "grep" từ dòng đầu tiên chứa "A" sang dòng tiếp theo:

printf "/A\n.+1,/A/p\nq" | ed -s

$ > foo echo "line 1
line 2A
line 3
line 4A
line 5"

$ sed -n '/2A/,$p' foo
line 2A
line 3
line 4A
line 5

$ sed -n '/2A/,/A/p' foo
line 2A
line 3
line 4A

$ printf "/A\n.+1,/A/p\nq" | ed -s foo
line 2A
line 3
line 4A

Có một gợi ý trong câu hỏi some_grep "A"gợi ý OP muốn phạm vi nhỏ nhất giữa hai dòng chứa "A". Xác định phạm vi từ / 2A / đến / A / là một trường hợp cụ thể và một cách giải quyết hơn là một câu trả lời.
techraf

@Techrat Tôi đang trả lời câu hỏi mà tôi đã trích dẫn trong câu trả lời của mình. Cấp có một mâu thuẫn với tham số được thông qua. Trả lời cập nhật.
jlliagre

Thật không may sed -n '/A/,/A/p'là một câu trả lời sai. Hãy thử nó với một tệp đầu vào có nhiều hơn hai dòng chứa "A".
techraf

@Techraf Thật vậy, câu trả lời được cập nhật lại.
jlliagre

1

Tôi nghĩ cách tốt nhất là sử dụng grepkết hợp với cuttail. Đầu tiên, sử dụng grep để lấy dòng có chuỗi mong muốn ( -nđến số dòng đầu ra; -m 1dừng tìm kiếm sau trận đấu đầu tiên):

grep -n -m 1 "somestring" filename.txt

Điều này xuất ra số dòng và chính chuỗi. Để cắt chuỗi, chúng tôi sử dụng cut ( -f1: trường đầu tiên đầu ra; -d:sử dụng ":" làm dấu phân cách):

grep -n -m 1 "somestring" filename.txt | cut -f1 -d:

Tiếp theo, chúng tôi sử dụng đầu ra của lệnh này làm tham số trong đuôi. Thông thường, đuôi in các dòng k cuối cùng, nhưng bằng cách sử dụng -n +k, chúng ta có đuôi để in từ dòng k trở đi. Tổng lệnh là:

tail -n +`grep -n -m 1 "somestring" filename.txt | cut -f1 -d:` filename.txt

Để đầu ra các dòng cho đến khi somestringsử dụng headthay vì tail-n -#thay vì -n +#. Bạn cũng có thể kết hợp cả hai để có được các dòng từ một chuỗi cho đến một chuỗi khác.


0

Vui lòng thử mã dưới đây -

sed -n '6,$p' infile

3
Bạn có thể biến điều này thành một "khoảnh khắc có thể dạy được" bằng cách mở rộng câu trả lời của bạn để giải thích lệnh không? Cảm ơn.
fixer1234

1
Điều này bỏ qua các điều kiện được chỉ định bởi OP trong lần đầu tiên và (ngay cả sau khi sửa đổi) không trả lời vấn đề thứ hai: từ "dòng 2A" đến dòng tiếp theo có chứa "A" .
techraf

0

Phương pháp sed là cách để đi, nhưng nếu bạn muốn giữ các dòng trên cùng, nhưng không grep chúng thì sao?

Đây là một cách:

{ head -1 file.txt ; sed 1d file.txt | grep <whatever> ;}

Những gì đang xảy ra ở đây?

Đầu tiên, chúng tôi nhổ ra dòng trên cùng (head -1 file.txt) Sau đó, chúng tôi xóa dòng trên cùng (sed 1d file.txt) và grep chỉ như vậy.

Toàn bộ mọi thứ được bao bọc bởi {..;}, do đó bạn có thể chuyển hướng hoặc chuyển hướng cả phần đầu và phần thân được ghép lại với nhau sau đó. Như thế này:

{đầu -1 file.txt; sed 1d file.txt | grep;}> newfile.txt

Nếu bạn muốn bỏ qua 10 dòng đầu tiên, hãy đổi nó thành dòng này

{đầu -10 file.txt; sed 1.10d file.txt | grep;}

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.