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).


Я попробовал -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. Но обычно это лучше для поиска по коду.


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 строк до и после каждого матча


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, что делает его очень эффективным для больших данных.


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параметры.


4
$ grep thestring thefile -5

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


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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.