Bagaimana saya memahami 50 baris pertama dari setiap file dalam direktori secara rekursif?

10

Saya perlu mencari 50 baris pertama dari setiap file dalam direktori dan subdirektori.

Ini akan melakukan bagian rekursif, tetapi bagaimana saya membatasi hanya 50 baris pertama dari setiap file?

grep -r "matching string here" .

Beberapa file ini sangat besar, dan saya hanya ingin mereka cocok dengan 50 baris pertama. Saya mencoba mempercepat proses dengan tidak mencari megabyte data biner di beberapa file.

zevlag
sumber
apakah Anda hanya ingin tahu file yang cocok, atau Anda ingin hanya memiliki string yang cocok atau Anda ingin string yang cocok bersama dengan nama file?
gniourf_gniourf

Jawaban:

11
  • Jika Anda hanya ingin file yang cocok:

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

    atau

    find . -type f -exec bash -c 'grep -q "matching string here" < <(head -n 50 "$1") && printf '%s\n' "$1"' _ {} \;
    
  • Jika Anda hanya menginginkan string yang cocok:

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

    atau lebih baik,

    find . -type f -exec head -q -n 50 {} + | grep "matching string here"
    
  • Dan jika Anda menginginkan keduanya:

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

Catatan.

  • Bisa sedikit lebih mudah dengan sedbukan dari kombo head- grep.
  • Biarkan saya tekankan bahwa ketiga metode ini 100% aman terkait nama file yang mungkin mengandung simbol lucu (spasi, baris baru, dll.).
  • Dalam dua metode ini, saya mengasumsikan Anda memiliki versi bash yang cukup baru.
  • Anda dapat menggunakan -exec ... +dalam setiap metode, tetapi Anda harus mengkodekan loop batin Anda sendiri! (latihan sepele diserahkan kepada pembaca). Ini mungkin sedikit lebih efisien jika Anda memiliki trilyun file.
gniourf_gniourf
sumber
4

Jika Anda memerlukan output grep seperti pada aslinya, Anda bisa melakukan:

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

Jika Anda hanya membutuhkan nama file, Anda dapat mengganti grep ke-2 dengan echo "$f".

Michael Suelmann
sumber
1

Anda harus menggabungkan beberapa utilitas berbeda untuk mendapatkan fungsionalitas yang diinginkan. Gunakan findperintah untuk mengulang direktori, temukan semua file dan jalankan headperintah pada setiap file yang ditemukan. The headperintah dapat digunakan untuk membuang hanya 50 baris pertama dari setiap file. Akhirnya, pipa keluaran ke grep untuk mencari string yang Anda inginkan.

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

Bulu anjing
sumber