Ограничьте вывод grep короткими строками

Я часто использую grep для нахождения файлов, имеющих определенную запись как это:

grep -R 'MyClassName'

Хорошая вещь состоит в том, что это возвращает файлы, их содержание и отмечает найденную строку красного цвета. Плохая вещь состоит в том, что у меня также есть огромные файлы, где весь текст записан в одной большой одной строке. Теперь выводы grep слишком много при нахождении текста в тех больших файлах. Существует ли способ ограничить вывод, например, 5 словами налево и направо? Или, возможно, ограничьте вывод 30 буквами налево и направо?

8
задан 18 April 2018 в 01:25

2 ответа

grep самостоятельно только имеет опции для контекста на основе строк. Альтернатива предлагается этим сообщением SU:

Обходное решение должно включить опции 'единственное соответствие' и затем использовать питание RegExp для grep немного больше, чем Ваш текст:

grep -o ".\{0,50\}WHAT_I_M_SEARCHING.\{0,50\}" ./filepath

Конечно, при использовании цветного выделения Вы можете всегда grep снова, чтобы только окрасить реальное соответствие:

grep -o ".\{0,50\}WHAT_I_M_SEARCHING.\{0,50\}"  ./filepath | grep "WHAT_I_M_SEARCHING"

Как другая альтернатива, я предложил бы foldлуг текст и затем захват его, например:

fold -sw 80 input.txt | grep ...

-s опция сделает fold продвиньте слова к следующей строке вместо того, чтобы повредиться промежуточный.

Или используйте некоторый другой способ разделить вход в строках на основе структуры Вашего входа. (Сообщение SU, например, имело дело с JSON, таким образом с помощью jq и т.д. к структурной распечатке программы и grep ... или просто использование jq чтобы сделать фильтрация отдельно... была бы лучше, чем любая из этих двух альтернатив, данных выше.)


Этот GNU awk метод мог бы быть быстрее:

gawk -v n=50 -v RS='MyClassName' '
  FNR > 1 { printf "%s: %s\n",FILENAME, p prt substr($0, 0, n)}
  {p = substr($0, length - n); prt = RT}
' input.txt
  • Скажите awk разделять записи на шаблоне, которым мы интересуемся (-v RS=...), и количество символов в контексте (-v n=...)
  • Каждая запись после первой записи (FNR > 1) тот где awk, найденный достойным шаблона.
  • Таким образом, мы печатаем n конечные символы от предыдущей строки (p) и n начальные символы от текущей строки (substr($0, 0, n)), наряду с подобранным текстом для предыдущей строки (который является prt)
    • мы устанавливаем p и prt после печати, таким образом, значение мы устанавливаем, используется следующей строкой
    • RT GNUism, вот почему это - awk-конкретный GNU.

Для рекурсивного поиска, возможно:

find . -type f -exec gawk -v n=50 -v RS='MyClassName' 'FNR>1{printf "%s: %s\n",FILENAME, p prt substr($0, 0, n)} {p = substr($0, length-n); prt = RT}' {} +
15
ответ дан 23 November 2019 в 05:27

Используя единственное соответствие в сочетании с некоторыми другими опциями (см. ниже), мог бы быть очень близко к тому, что Вы ищете без обработки наверху regex, упомянутого в другом ответе

grep -RnHo 'MyClassName'
  • n числовой вывод, покажите номер строки соответствия
  • H имя файла, покажите имя файла в начале строки соответствия
  • o только соответствует, только покажите соединяемую строку, не целую строку
1
ответ дан 23 November 2019 в 05:27

Другие вопросы по тегам:

Похожие вопросы: