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

  • UUID fb... является разделом. От информации выше, не возможно сказать, является ли это/dev/sda или что-либо еще.

  • proc, sysfs, devpts являются виртуальными файловыми системами

  • tmpfs является некоторой подобной электронному диску файловой системой

  • /usr/tmpDSK кажется, файл, который используется в качестве изображения для монтирования/tmp

33
23.11.2016, 16:07
3 ответа

В GNU grep:

N=10; grep -roP ".{0,$N}foo.{0,$N}" .

Объяснение:

  • -o => Печатайте только то, что соответствовало
  • -P => Используйте регулярные выражения в Perl-стиле
  • Регекс говорит, что соответствуют от 0 до $N символов, за которыми следуют foo, за которыми следуют от 0 до $N символов.

Если у вас нет GNU grep:

find . -type f -exec \
    perl -nle '
        BEGIN{$N=10}
        print if s/^.*?(.{0,$N}foo.{0,$N}).*?$/$ARGV:$1/
    ' {} \;

Пояснение:

Поскольку мы больше не можем полагаться на то, что grep является GNU grep, мы используем find для рекурсивного поиска файлов (действие -r GNU grep). Для каждого найденного файла мы выполняем фрагмент Perl.

Переключатели Perl:

  • -n Чтение файла строка за строкой
  • -l Удаляем новую строку в конце каждой строки и возвращаем ее обратно при печати
  • -e Обращайтесь со следующей строкой как с кодом

Фрагмент Perl делает по существу то же самое, что и grep grep. Он начинается с установки переменной $N необходимого количества символов контекста. Значение BEGIN{} означает, что она выполняется только один раз в начале выполнения, а не один раз для каждой строки в каждом файле.

Операция, выполняемая для каждой строки, заключается в выводе строки, если работает регекс-подстановка.

Регекс:

  • Соответствует любой старой вещи лениво1 в начале строки (^.*?), за которой следует . {0,$N}, как в случае grep, за которым следует foo, за которым следует другая .{0,$N} и, наконец, сопоставление любой старой вещи лениво до конца строки (.*?$).
  • Заменяем это на $ARGV:$1. $ARGV - это магическая переменная, содержащая имя читаемого текущего файла. $1 - это то, чему соответствуют пары: контекст в данном случае.
  • Ленивые совпадения на обоих концах необходимы, так как жадное совпадение съест все символы до foo, не имея совпадения (так как .{0,$N} разрешено совпадение нулевых времен).

1То есть, предпочтительнее ничего не сопоставлять, если только это не приведет к неудаче общего совпадения. Одним словом, соответствуйте как можно меньшему количеству символов.

24
27.01.2020, 19:37

Попробуйте использовать это:

grep -r -E -o ".{0,10}wantedText.{0,10}" *

-E говорит, что вы хотите использовать расширенный регекс

-o говорит, что вы хотите распечатать только совпадения

-r grep ищет результат рекурсивно в папке

REGEX:

{0,10} сообщает, сколько произвольных символов вы хотите напечатать

. представляет собой произвольный символ (сам символ здесь не важен, только их количество)

Edit: О, я вижу, что Джозеф рекомендует почти такое же решение, как и я :D

.
20
27.01.2020, 19:37

Взято из: http://www.topbug.net/blog/2016/08/18/truncate-long-matching-lines-of-grep-a-solution-that-preservations-color/ и https://stackoverflow.com/a/39029954/1150462

Предлагаемый подход ". {0,10} <исходный шаблон>. {0,10} " отлично подходит, за исключением того, что цвет выделения часто искажается. Я создал сценарий с аналогичным выводом, но цвет также сохранился:

#!/bin/bash

# Usage:
#   grepl PATTERN [FILE]

# how many characters around the searching keyword should be shown?
context_length=10

# What is the length of the control character for the color before and after the matching string?
# This is mostly determined by the environmental variable GREP_COLORS.
control_length_before=$(($(echo a | grep --color=always a | cut -d a -f '1' | wc -c)-1))
control_length_after=$(($(echo a | grep --color=always a | cut -d a -f '2' | wc -c)-1))

grep -E --color=always "$1" $2 | grep --color=none -oE ".{0,$(($control_length_before + $context_length))}$1.{0,$(($control_length_after + $context_length))}"

Предполагая, что сценарий сохранен как grepl , тогда шаблон grepl file_with_long_lines должен отображать совпадающие строки, но всего 10 символов вокруг соответствующей строки.

2
27.01.2020, 19:37

Передача стандартного вывода в cutс флагом -b; вы можете настроить вывод grep только на байты от 1 до 400 на строку.

grep "foobar" * | cut -b 1-400
24
27.01.2020, 19:37

Теги

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