Як я можу реєструвати перші 50 рядків кожного файлу в каталозі?


10

Мені потрібно шукати перші 50 рядків кожного файлу в каталозі та його підкаталогах.

Це зробить рекурсивну частину, але як я обмежуся лише першими 50 рядками кожного файлу?

grep -r "matching string here" .

Деякі з цих файлів величезні, і я хочу лише, щоб вони співпадали в перших 50 рядках. Я намагаюся прискорити процес, не шукаючи мегабайт бінарних даних у деяких файлах.


чи хочете ви просто знати файли, які відповідають, чи ви хочете мати лише відповідний рядок, чи ви хочете, щоб відповідна рядок разом із іменем файлу?
gniourf_gniourf

Відповіді:


11
  • Якщо ви просто хочете, щоб файли відповідали:

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

    або

    find . -type f -exec bash -c 'grep -q "matching string here" < <(head -n 50 "$1") && printf '%s\n' "$1"' _ {} \;
    
  • Якщо ви хочете лише відповідні рядки:

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

    або, краще,

    find . -type f -exec head -q -n 50 {} + | grep "matching string here"
    
  • І якщо ви хочете обох:

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

Зауваження.

  • Можливо, трохи легше з sedкомбо head- grep.
  • Дозвольте наголосити, що всі три методи на 100% безпечні щодо імен файлів, які можуть містити забавні символи (пробіли, нові рядки тощо).
  • У двох із цих методів я припускаю, що у вас є пристойно недавня версія bash.
  • Ви можете використовувати -exec ... +в кожному методі, але тоді вам доведеться самостійно кодувати свій внутрішній цикл! (тривіальна вправа, залишена читачеві). Це може бути дуже дещо ефективніше, якщо у вас є файли в gazillion.

4

Якщо вам потрібен вихід греп, як у оригіналі, ви можете зробити:

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

Якщо вам потрібні лише імена файлів, ви можете замінити 2-й греп echo "$f".


1

Вам потрібно буде поєднати кілька різних утиліт, щоб отримати бажаний функціонал. Використовуйте findкоманду для повторного запуску каталогів, пошуку всіх файлів та виконання headкоманди на кожному знайденому файлі. headКоманда може бути використана для дампа тільки перші 50 рядків кожного файлу. Нарешті, підключіть висновок до grep для пошуку потрібного рядка.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.