grep файл, но показать несколько окружающих строк?

3422

Я хотел бы grepдля строки, но также показать предыдущие пять строк и следующие пять строк, а также соответствующие строки. Как я смогу сделать это?

Марк Харрисон
источник
3
Для этой цели я держу копию perl-скрипта Брендана Грегга . Работает хорошо.
Итан Пост
6
Для решения, которое работает на Solaris, проверьте эту ссылку .
Джахрой
107
man grep | grep -C 1 context:)
StvnW
20
man grep | grep -C 1 "\-C";)
Андерс Б.
9
@StvnW ... Я не знаю, следует ли называть эту мету (в более общем, а не SO-контексте) или как ее назвать. Вы ответили на вопрос, показав, как использовать ответ, чтобы найти ответ.
bballdave025

Ответы:

4540

Для BSD или GNU grep вы можете использовать, -B numчтобы указать, сколько строк перед совпадением и -A numсколько строк после совпадения.

grep -B 3 -A 2 foo README.txt

Если вы хотите одинаковое количество строк до и после вы можете использовать -C num.

grep -C 3 foo README.txt

Это покажет 3 строки до и 3 строки после.

Пэт Нотц
источник
56
Это хорошо, но, к сожалению, grep Solaris не поддерживает это. Смотрите эту ссылку для Соляриса: unix.com/solaris/33533-grep-display-few-lines-before-after.html
рüффп
9
Хорошо, но что, если хотите показать все строки вывода после матча? grep -A0 и grep -A-1 не режут ...
g33kz0r
2
по какой-то причине у меня не работает, хотя упоминается в моих справочных страницах.
Хайри Угур Колтук
2
Если вы HP-UX env, ни одна из версий grep не будет работать так же, как в Solaris. Был в состоянии использовать ссылку Solaris, но в этой ссылке заменил nawk на awk.
zkarthik
6
-n для номеров строк, но для некоторых версий grep -n # будет показывать # окружающие строки (например, -c) с номерами строк. Это полезный ярлык, который мне нужен, когда мне нужен контекст.
Энтони ДиСанти
607

-A а также -B будет работать, как будет -C n(для nстрок контекста) или просто -n(для nстрок контекста ... до тех пор, пока n равно от 1 до 9).

Stu
источник
Я попробовал -nформат и обнаружил, что он работает только до 9. Ибо 15он возвращает 5 строк
Дипак Махакале
8
@DeepakMahakale Это, вероятно, связано с тем, как аргументы / параметры командной строки обычно анализируются программами POSIX. Спецификатор параметра - это один символ (например -A, -Bили -C). Обычно за параметром опции следует значение ( -o a.outдля указания выходного файла в GCC), но он также может функционировать как простой переключатель / флаг ( -gдля включения информации отладки в GCC). Однако пробелы между опциями являются необязательными, поэтому для опций без значения можно объединить их ( -ABC), что означает, что -15интерпретируется -1 -5(две отдельные опции) и -5переопределяется -1.
natiiix
1
-5 быстрее, чем оба -A 5 -B 5. Они не предназначены для совместного использования. Другим читателям скрипта будет чище, если вы выберете -A или -B или -C вместо -9.
Эрик
77

ack работает с аргументами, аналогичными grep, и принимает -C. Но обычно это лучше для поиска по коду.

Elmarco
источник
5
ack также поддерживает -A -B.
Шуо
Ack лучше, чем grep во многих отношениях. Это быстрее с более простым синтаксисом.
Хим
1
Преимущество grep заключается в том, что он устанавливается по умолчанию во многих системах.
Марк З.
1
@MarcZ: Да, по умолчанию grep устанавливается чаще, чем ack, но ack - это переносимый автономный скрипт. Нет необходимости компилировать его или устанавливать в системный каталог, такой как / usr / bin /. Как только он загружен и помещен в каталог, указанный в $ PATH (и установлен бит разрешения eXecute), он должен работать сразу же. (Для доступа к работе не требуются привилегии sudo или root.)
JL
Этот вопрос о том grep, не стоит ли использовать его для «рекламы» ack(что действительно является отличным инструментом) - хорошая идея…
MonsieurDart
39
grep astring myfile -A 5 -B 5

Это будет grep "myfile" для "astring", и покажет 5 строк до и после каждого матча

DBR
источник
19
"grep astring myfile -C 5" будет делать то же самое
Сайед Сирадж Уддин
20

Я обычно пользуюсь

grep searchstring file -C n # n for number of lines of context up and down

Многие инструменты, такие как grep, также имеют действительно отличные файлы man. Я часто обращаюсь к справочной странице grep, потому что с ней можно многое сделать.

man grep

Многие инструменты GNU также имеют информационную страницу, которая может содержать более полезную информацию в дополнение к странице руководства.

info grep
Сэм Меррелл
источник
13

Использовать grep

$ grep --help | grep -i context
Context control:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context
  -C, --context=NUM         print NUM lines of output context
  -NUM                      same as --context=NUM
Чиль тен бринке
источник
Вы не читали принятый ответ? Вы просто повторяете то, что уже было сказано по вопросу, которому почти 10 лет ...
Йокай
7
Ой, прости, Йокай. Но я ничего не читаю о поиске ответа в разделе справки grep.
Чиль тен Бринке
1
@Yokai Кроме того, что сказал Чил тен Бринке, в принятом ответе не упоминаются длинные варианты
user3738870
11

Ищите «17655» в «/some/file.txt», показывая контекст из 10 строк до и после (с помощью Awk), выводу предшествует номер строки и двоеточие. Используйте это в Solaris, когда 'grep' не поддерживает опции «- [ACB]».

awk '

/17655/ {
        for (i = (b + 1) % 10; i != b; i = (i + 1) % 10) {
                print before[i]
        }
        print (NR ":" ($0))
        a = 10
}

a-- > 0 {
        print (NR ":" ($0))
}

{
        before[b] = (NR ":" ($0))
        b = (b + 1) % 10
}' /some/file.txt;
Малкольм Бекхофф
источник
7

ripgrep

Если вы заботитесь о производительности, используйте ripgrepсинтаксис, аналогичный grep, например,

rg -C5 "pattern" .

-C, --context NUM- Показать ЧИСЛО строк до и после каждого матча.

Есть также такие параметры, как -A/ --after-contextи -B/ --before-context.

Инструмент построен на основе движка регулярных выражений Rust, что делает его очень эффективным для больших данных.

kenorb
источник
5

Вот решение @Ygor вawk

awk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=3 a=3 s="pattern" myfile

Примечание. Замените aи bпеременные числом строк до и после.

Это особенно полезно для системы , которая не поддерживает Grep - х -A, -Bи -Cпараметры.

kenorb
источник
4
$ grep thestring thefile -5

-5получает вас 5строку выше и ниже матч «thestring» эквивалентен -C 5или -A 5 -B 5.

JBone
источник
4

Grep имеет опцию под названием Context Line Control, вы можете использовать --contextв этом, просто,

| grep -C 5

или

| grep -5

Должен сделать трюк

простое число
источник
1

Я использую, чтобы сделать компактный способ

grep -5 string file

Это эквивалент

grep -A 5 -B 5 string file
Франциска
источник
0

Если вы часто выполняете поиск по коду, AG серебряный искатель гораздо эффективнее (т.е. быстрее), чем grep.

Вы показываете контекстные строки, используя опцию -C.

Например:

ag -C 3 "foo" myFile

line 1
line 2
line 3
line that has "foo"
line 5
line 6
line 7
Роза
источник