Làm cách nào để tôi grep 50 dòng đầu tiên của mỗi tệp trong một thư mục theo cách đệ quy?


10

Tôi cần tìm kiếm 50 dòng đầu tiên của mỗi tệp trong một thư mục và các thư mục con của nó.

Điều này sẽ làm phần đệ quy, nhưng làm cách nào để giới hạn chỉ 50 dòng đầu tiên của mỗi tệp?

grep -r "matching string here" .

Một số tệp này rất lớn và tôi chỉ muốn chúng khớp trong 50 dòng đầu tiên. Tôi đang cố gắng tăng tốc quá trình bằng cách không tìm kiếm megabyte dữ liệu nhị phân trong một số tệp.


Bạn có muốn chỉ biết các tệp phù hợp hoặc bạn muốn chỉ có chuỗi phù hợp hoặc bạn muốn chuỗi phù hợp cùng với tên tệp?
gniourf_gniourf

Câu trả lời:


11
  • Nếu bạn chỉ muốn các tập tin phù hợp:

    find . -type f -exec bash -c 'grep -q "matching string here" < <(head -n 50 "$1")' _ {} \; -printf '%p\n'
    

    hoặc là

    find . -type f -exec bash -c 'grep -q "matching string here" < <(head -n 50 "$1") && printf '%s\n' "$1"' _ {} \;
    
  • Nếu bạn chỉ muốn các chuỗi phù hợp:

    find . -type f -exec head -n 50 {} \; | grep "matching string here"
    

    hoặc tốt hơn,

    find . -type f -exec head -q -n 50 {} + | grep "matching string here"
    
  • Và nếu bạn muốn cả hai:

    find . -type f -exec bash -c 'mapfile -t a < <(head -n 50 "$1" | grep "matching string here"); printf "$1: %s\n" "${a[@]}"' _ {} \;
    

Nhận xét.

  • Có thể dễ dàng hơn một chút với sedthay vì kết hợp head- grep.
  • Hãy để tôi nhấn mạnh rằng cả ba phương pháp đều an toàn 100% liên quan đến tên tệp có thể chứa các ký hiệu vui nhộn (dấu cách, dòng mới, v.v.).
  • Trong hai trong số các phương pháp này, tôi giả sử bạn có một phiên bản bash gần đây.
  • Bạn có thể sử dụng -exec ... +trong từng phương thức, nhưng sau đó bạn sẽ phải tự viết mã cho vòng lặp bên trong của mình! (bài tập tầm thường để lại cho người đọc). Điều này có thể sẽ hiệu quả hơn một chút nếu bạn có một tập tin gazillion.

4

Nếu bạn cần đầu ra grep như trong bản gốc, bạn có thể làm:

find . -type f | while read f; do 
  if head -n 50 "$f"|grep -s "matching string here"; then
    grep "matching string here" "$f" /dev/null 
  fi
done

Nếu bạn chỉ cần tên tệp, bạn có thể thay thế grep thứ 2 bằng echo "$f".


1

Bạn sẽ cần kết hợp một vài tiện ích khác nhau để có được chức năng mong muốn. Sử dụng findlệnh để lặp lại các thư mục, tìm tất cả các tệp và thực hiện headlệnh trên mỗi tệp được tìm thấy. Các headlệnh có thể được sử dụng để đổ chỉ trong 50 dòng đầu tiên của mỗi tập tin. Cuối cùng, chuyển đầu ra sang grep để tìm kiếm chuỗi mong muốn của bạn.

find . -type f -exec head -n 50 {} ";" | grep "matching string here"

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.