Я должен пролистать некоторые JSON-файлы, в которых длина строк превышает несколько тысяч символов. Как я могу ограничить grep для отображения контекста до N символов слева и справа от совпадения? Подойдет любой инструмент, кроме grep, если он доступен в обычных пакетах Linux.
Это будет пример вывода для воображаемого переключателя grep Ф :
$ grep -r foo *
hello.txt: Once upon a time a big foo came out of the woods.
$ grep -Ф 10 -r foo *
hello.txt: ime a big foo came of t
Ответы:
С GNU
grep
:Объяснение:
-o
=> Печатайте только то, что вам подходит-P
=> Используйте регулярные выражения в стиле Perl$N
символам, затемfoo
следует 0$N
символам.Если у вас нет GNU
grep
:Объяснение:
Поскольку мы больше не можем полагаться на
grep
тоgrep
, чтобы быть GNU , мы используемfind
рекурсивный поиск файлов (-r
действие GNUgrep
). Для каждого найденного файла мы выполняем фрагмент Perl.Perl переключатели:
-n
Читать файл построчно-l
Удалите новую строку в конце каждой строки и вставьте ее обратно при печати-e
Рассматривайте следующую строку как кодФрагмент Perl делает практически то же самое, что и
grep
. Он начинается с установки переменной$N
на количество символов контекста, которые вы хотите. ЭтоBEGIN{}
означает, что это выполняется только один раз в начале выполнения, а не один раз для каждой строки в каждом файле.Оператор, выполняемый для каждой строки, должен напечатать строку, если подстановка регулярного выражения работает.
Регулярное выражение:
^.*?
), затем,.{0,$N}
как вgrep
случае, за которойfoo
следует другая,.{0,$N}
и, наконец, сопоставьте любую старую вещь лениво до конца строки (.*?$
).$ARGV:$1
.$ARGV
является магической переменной, которая содержит имя текущего файла для чтения.$1
вот что совпало с паренсом: контекст в данном случае.foo
без совпадения (так.{0,$N}
как разрешено совпадать ноль раз).1 То есть, предпочитайте не сопоставлять что-либо, если только это не приведет к сбою в общем совпадении. Короче говоря, подберите как можно меньше символов.
источник
| grep foo
в конец (однако при этом теряется выделение имени файла в процессе).grep
вы можете указать соответствие цветов / приложений на основе флагов, применяемых через переменные среды. так что, возможно, даже вы могли бы выиграть их всех (без обещаний - даже не уверен, что это сработает в этом случае), но я лично не вижу здесь уместности ... в любом случае ... продолжайте игратьzsh
я не могу заставить его работать, передавая N = 10, как в примере. Однако это работает, если яexport N=10
до запуска команды. Есть идеи, как настроить пример для работы с Zsh?perl -lne 'print "$ARGV: $_" for /.{0,10}foo.{0,10}/g'
Попробуйте использовать это:
-E говорит, что вы хотите использовать расширенное регулярное выражение
-о говорит, что вы хотите напечатать только матч
-r grep рекурсивно ищет результат в папке
REGEX:
{0,10} говорит, сколько произвольных символов вы хотите напечатать
, представляет произвольный символ (сам символ здесь не важен, только их количество)
Редактировать: О, я вижу, что Джозеф рекомендует почти то же решение, что и я: D
источник
-E
значительно быстрее чем-P
.Взято из: http://www.topbug.net/blog/2016/08/18/truncate-long-matching-lines-of-grep-a-solution-that-preserved-color/ и https: // stackoverflow. ком / а / 39029954/1150462
Предлагаемый подход
".{0,10}<original pattern>.{0,10}"
очень хорош, за исключением того, что цвет подсветки часто путается. Я создал скрипт с похожим выводом, но цвет также сохранился:Предполагая, что скрипт сохранен как
grepl
, тогдаgrepl pattern file_with_long_lines
должны отображаться соответствующие строки, но только с 10 символами вокруг соответствующей строки.источник
Трубопровод
cut
с-b
флагом; вы можете настроить вывод grep только на байты от 1 до 400 на строку.источник