it-swarm-vi.com

Hiển thị tất cả các tập tin lên đến trận đấu

grep --before-context 5 hiển thị 5 dòng trước trận đấu.

Tôi muốn thể hiện mọi thứ trước trận đấu.
Đang làm grep --before-context 99999999 sẽ hoạt động nhưng nó không ... chuyên nghiệp lắm.

Làm thế nào để hiển thị tất cả các tập tin lên đến trận đấu?

78
Nicolas Raoul

Sed là tốt hơn cho điều đó.

Cứ làm đi:

sed '/PATTERN/q' FILE

Nó hoạt động như thế này:

Đối với mỗi dòng, chúng tôi xem nếu nó phù hợp với /PATTERN:

  • nếu có, chúng tôi in nó và thoát
  • mặt khác, chúng tôi in nó

Đây là giải pháp hiệu quả nhất, vì ngay khi thấy PATTERN, nó đã thoát. Không có q, sed sẽ tiếp tục đọc phần còn lại của tệp và không làm gì với nó. Đối với các tập tin lớn, nó có thể làm cho một sự khác biệt.

Thủ thuật này cũng có thể được sử dụng để mô phỏng head:

sed 10q FILE
104
Mikel

sed có thể thay thế hầu hết chức năng của grep.

sed -n '1,/<pattern>/ p' <file>

Điều này có nghĩa là in từ dòng đầu tiên cho đến khi mẫu được khớp.

Một vài ví dụ

sed -n '/<pattern>/,$ p' <file> # from pattern to end of file
sed -n '/<pattern1>/,/<pattern2>/ p' <file> # from pattern1 to pattern2
39
forcefsck

in lên và bao gồm cả trận đấu:

awk '{print} /pattern/ {exit}' filename
sed '/pattern/q' filename

in lên NHƯNG KHÔNG bao gồm trận đấu:

awk '/pattern/ {exit} {print}' filename
sed '/pattern/Q' filename
39
glenn jackman

Đối với những người chọn chỉ nhớ các công cụ cơ bản trong công việc hàng ngày và sẵn sàng chấp nhận các giải pháp kém thanh lịch và kém hiệu quả hơn:

head -n $(grep -n pattern filename | cut -d: -f1) filename

Nếu lệnh này là cho một kịch bản thì tôi sẽ tìm kiếm các giải pháp thanh lịch hơn (và có thể hiệu quả). Nếu đây là lệnh một lần hoặc kịch bản vứt đi thì tôi không quan tâm.

1
lesmana

Thêm vào câu trả lời của Mikel ở trên ...


Để in tất cả các dòng lên đến, nhưng không bao gồm , dòng đầu tiên trong FILE có chứa PATTERN, hãy thử:

  • sed '/.*PATTERN.*/{s///;q;}' FILE

Điều này khớp với toàn bộ dòng chứa mẫu, thay thế nó bằng một dòng trống, sau đó thoát ra mà không xử lý phần còn lại của tệp.


Kịch bản sau:

Cách dễ nhất/rõ ràng nhất mà tôi có thể nghĩ ra để ngăn việc in thêm một dòng mới ở cuối (không liên quan đến công cụ khác), là chạy lại sed và xóa dòng cuối cùng mới:

sed '/.*PATTERN.*/{s///;q;}' FILE | sed '$d'

... và vì hiện tại chúng tôi đang xóa dòng đó, công việc trước đây của chúng tôi là không cần thiết và chúng tôi có thể đơn giản hóa để:

sed '/PATTERN/q' FILE | sed '$d'
1
Jim Grisham

Các phương thức thuần túy GNU grep không hiệu quả.

Tìm kiếm mọi thứ lên đến đầu tiên của chuỗi " foo " trong thanh tệp , sử dụng ba greps:

grep -m 1 -B $(grep -n -m 1 foo bar | grep -o '^[0-9]*') foo bar

Khớp với trường hợp cuối cùng của " foo ":

grep -oPz "(?s)[^\n]*${s}.*?\n.*?foo.*?\n" bar

Lưu ý: chi tiết về grep cuối cùng có thể được tìm thấy trong: Regex (grep) cho tìm kiếm nhiều dòng cần thiết .

1
agc

Bạn cũng có thể sử dụng một trong những điều sau đây

tac ./test | grep -B $(cat ./test | wc -l) -m 1 'pattern'|tac 

hoặc là

tac ./test |head -n $(tac ./test | grep -n 'pattern' | cut -d: -f1 | head -n 1)|tac

hoặc là

tac ./test |sed ':a;N;$!ba;s/\n/'"pattern"'/g' | sed 's/'"patternpattern"'/\n/g'|head -n 1|sed 's/'"pattern"'/\n/g'|tac

Tùy chọn đầu tiên rất giống với những gì OP đề xuất, chỉ đảm bảo rằng ti hiển thị đủ các dòng trước ngữ cảnh bằng cách đếm các dòng trong tệp

Tùy chọn thứ hai tìm kiếm số dòng của trận đấu đầu tiên (bạn cũng có thể thay đổi số đó bằng cách thay đổi 'đầu' bên trong) và sử dụng đầu trên số đó

Tùy chọn cuối cùng thay thế tất cả các dòng mới bằng trận đấu và thay thế hai trận đấu liền kề bằng một dòng mới. Đầu ra của điều này là một dòng cho mỗi khối văn bản giữa hai kết quả khớp. Sau đó, nó sử dụng 'head' để chọn dòng đầu tiên (thay đổi khối văn bản cho đến khi khớp đầu tiên) khớp và hơn là truyền lại mỗi trận đấu sang một dòng mới. tùy chọn này chỉ hoạt động nếu tệp có định dạng sau

pattern
texttexttext
texttexttext texttexttext
texttexttexttexttexttexttexttexttext
pattern
texttexttext
pattern 
texttexttext
texttexttexttexttexttexttexttexttext

và kể từ đó trở đi

0
user122778