Come posso ricorrere in modo ricorsivo alle prime 50 righe di ciascun file in una directory?


10

Devo cercare le prime 50 righe di ogni file in una directory e nelle sue sottodirectory.

Questo farà la parte ricorsiva, ma come posso limitare solo alle prime 50 righe di ciascun file?

grep -r "matching string here" .

Alcuni di questi file sono enormi e voglio solo che corrispondano nelle prime 50 righe. Sto cercando di accelerare il processo non cercando megabyte di dati binari in alcuni file.


vuoi conoscere solo i file corrispondenti o vuoi avere solo la stringa corrispondente o vuoi la stringa corrispondente insieme al nome del file?
gniourf_gniourf,

Risposte:


11
  • Se vuoi solo i file corrispondenti:

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

    o

    find . -type f -exec bash -c 'grep -q "matching string here" < <(head -n 50 "$1") && printf '%s\n' "$1"' _ {} \;
    
  • Se vuoi solo le stringhe corrispondenti:

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

    o meglio,

    find . -type f -exec head -q -n 50 {} + | grep "matching string here"
    
  • E se vuoi entrambi:

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

Osservazioni.

  • Potrebbe essere leggermente più semplice con sedinvece della combo head- grep.
  • Vorrei sottolineare che tutti e tre i metodi sono sicuri al 100% per quanto riguarda i nomi dei file che possono contenere simboli divertenti (spazi, newline, ecc.).
  • In due di questi metodi, suppongo che tu abbia una versione abbastanza recente di bash.
  • Puoi usare -exec ... +ogni metodo, ma poi dovrai codificare tu stesso il tuo ciclo interno! (esercizio banale lasciato al lettore). Questo potrebbe essere leggermente più efficiente se hai un file gazillion.

4

Se hai bisogno dell'output grep come nell'originale, puoi fare:

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

Se hai solo bisogno dei nomi dei file, puoi sostituire il 2 ° grep con echo "$f".


1

Dovrai combinare alcune utility diverse per ottenere la funzionalità desiderata. Utilizzare il findcomando per richiamare le directory, trovare tutti i file ed eseguire il headcomando su ogni file trovato. Il headcomando può essere usato per scaricare solo le prime 50 righe di ciascun file. Infine, reindirizza l'output a grep per cercare la stringa desiderata.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.