Grep: đếm số lượng trận đấu trên mỗi dòng


26

Tôi đang cố gắng để có được số lượng kết quả khớp (trong trường hợp này là {hoặc }) trong mỗi dòng của tệp .tex.

Tôi biết rằng -ocờ chỉ trả về trận đấu, nhưng nó trả về mỗi trận đấu trên một dòng mới, thậm chí kết hợp với -ncờ. Tôi không biết bất cứ điều gì tôi có thể bỏ qua điều này để đếm số lần lặp lại. Các -clá cờ chỉ trả về tổng số các trận đấu trong toàn bộ tập tin - có lẽ tôi có thể ống một dòng tại một thời điểm để grep?

Câu trả lời:


27
grep -o -n '[{}]' <filename> | cut -d : -f 1 | uniq -c

Đầu ra sẽ giống như:

3 1
1 2

Có nghĩa là 3 lần xuất hiện trong dòng đầu tiên và 1 trong lần thứ hai.

Lấy từ /programming//a/15366097/3378354 .


Cảm ơn - google đã tìm thấy rất nhiều lượt truy cập regex trên SU, nhưng không phải là lượt truy cập trên SO, thậm chí dường như không có thẻ regex. Điều sortnày không thực sự cần thiết vì đầu ra của grep được sắp xếp theo số dòng, nhưng tôi đoán đó là cách thực hành tốt trước đây uniq.
Chris H

2
Có lẽ không được gắn thẻ regexvì regex là phần dễ dàng.
Tom Zych

Có thực sự cần thiết sort -n? Không phải nó đi ra theo thứ tự số dòng sao?
Tom Zych

Bạn đúng, sort -nkhông cần thiết. Cảm ơn.
Moebius

@TomZych, hóa ra bạn đã đúng, nhưng tôi có biết rằng tôi có thể không hỏi. Bước nhảy tinh thần từ grep sang tag: regex có lẽ hơi quá.
Chris H

3

Sau khi đọc các giải pháp khác nhau, tôi nghĩ rằng đây là cách tiếp cận dễ dàng nhất cho vấn đề:

while read i; do echo $i |grep -o "matchingString"| wc -l;  done < input.txt

3
Giải pháp tốt nhất, theo tôi. Có thể được đơn giản hóa hơn nữa bằng cách giảm bằng một ống : grep -o "matchingString" <<< $i | wc -l.
Benjamin W.

1
Tuy nhiên, đây sẽ là những đơn đặt hàng có cường độ chậm hơn các lựa chọn khác
Rahul

1

Là sử dụng grepmột yêu cầu? Đây là một thay thế:

sed 's / [^ {}] // g' your_file | awk '{in NR, chiều dài}'

Các seddải ra tất cả các nhân vật khác hơn {} (ví dụ, chỉ để lại {}ký tự), và sau đó awkđếm các ký tự trên mỗi dòng (mà chỉ là {}ký tự). Để chặn các dòng không có kết quả khớp,

sed 's / [^ {}] // g' your_file | awk '/./ {in NR, độ dài}'

Lưu ý rằng giải pháp của tôi giả định (yêu cầu) rằng các chuỗi bạn đang tìm kiếm là các ký tự đơn. Câu trả lời của Moebius dễ dàng thích nghi hơn với chuỗi nhiều ký tự. Ngoài ra, không có câu trả lời nào của chúng tôi loại trừ các lần xuất hiện được trích dẫn hoặc thoát khỏi các ký tự / chuỗi quan tâm; ví dụ,

{ "nullfunc() {}" }

sẽ được coi là có chứa bốn nhân vật cú đúp.


grepthực sự không phải là một yêu cầu, đó chỉ là nơi tôi bắt đầu tìm kiếm giải pháp, bởi vì nó mang lại cho tôi điều gì đó gần gũi. Tôi chưa bao giờ có nhu cầu về awk, vì vậy tôi đã không sử dụng câu trả lời ở trên Tôi đã sử dụng điều này như một cơ hội để thử nghiệm - tôi vẫn có thể. Điều tôi thất bại trong việc làm rõ (nhưng nó không ảnh hưởng đến câu trả lời) là tôi muốn chạy tập lệnh một lần trên mỗi khung, để giúp tôi theo dõi một sự không phù hợp (trong nguồn LaTeX, ở đây cho một bảng) trong đó hầu hết các cặp xảy ra trong một dòng duy nhất.
Chris H

Tôi không chắc ý của bạn là gì khi chạy kịch bản một lần trên mỗi khung, nhưng nếu bạn muốn theo dõi một sự không phù hợp của niềng răng, bạn có thể muốn thử một cái gì đó như sed 's/{[^{}]*}//g' your_file | grep –n '[{}]', trong đó các cặp seddải (khớp). Nếu bạn có các cặp lồng nhau, hãy sử dụng sed 's/{[^{}]*}//g;s/{[^{}]*}//g;s/{[^{}]*}//g;…' …, lặp lại s/{[^{}]*}//gnhiều lần như lần lồng sâu nhất của bạn.
Scott

Ý tôi là thực thi `sed 's / [^}] // g' your_file | awk '{in NR, chiều dài}' và 's / [^ {] // g' your_file | awk '{in NR, chiều dài}'. Tôi thực sự có làm tổ, và làm việc ở cấp độ sâu nhất có vẻ như là một việc vặt. Biến nhiều dòng thành một số ít (có một vài trường hợp niềng răng chỉ khớp với nhiều dòng vì lý do hợp lệ) hoạt động tốt (tôi sử dụng jedit làm nổi bật dấu ngoặc phù hợp - cho bất kỳ loại khung nào nó hiểu - vì vậy tôi thực sự đã làm chỉ cần thu hẹp nó xuống).
Chris H
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.