8

Мне нужно искать первые 50 строк каждого файла в каталоге и его подкаталогах.

Это сделает рекурсивную часть, но как ограничить только первые 50 строк каждого файла?

grep -r "matching string here" .

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

3 ответа3

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

Если вам нужен вывод grep, как в оригинале, вы можете сделать:

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-й grep на echo "$f" .

1

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .