зібрати файл, але показати кілька навколишніх ліній?


3417

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


3
З цією метою я зберігаю копію сценарію Perl Брендана Грегга . Добре працює.
Ethan Post

6
Для рішення, яке працює на Solaris, перегляньте це посилання .
jahroy

106
man grep | grep -C 1 context:)
StvnW

20
man grep | grep -C 1 "\-C";)
Андерс Б

9
@StvnW ... Я не знаю, чи слід називати цей мета (у більш загальному, а не в контексті SO), або як його викликати. Ви відповіли на питання, показавши, як використовувати відповідь, щоб знайти відповідь.
bballdave025

Відповіді:


4535

Для 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
Це добре, але, на жаль, греп Solaris цього не підтримує. Дивіться це посилання на solaris: unix.com/solaris/33533-grep-display-few-lines-before-after.html
рюфф

9
Гаразд, але що робити, якщо хочете показати всі рядки результатів після матчу? grep -A0 і grep -A-1 не вирізати ...
g33kz0r

2
чомусь не працює для мене, хоча згадується на сторінках моєї людини.
Hayri Uğur Koltuk

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 рядків
Діпак

7
@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.
Ерік

76

ack працює з аналогічними аргументами, як grep, і приймає -C. Але зазвичай краще шукати код.


5
ack також підтримує -A -B.
Шуо

Ack краще, ніж grep в багатьох відношеннях. Це швидше за допомогою більш простого синтаксису.
шим

1
grep має перевагу в тому, що він встановлюється за замовчуванням у багатьох системах.
Marc Z

1
@MarcZ: Правда, grep швидше буде встановлений за замовчуванням, ніж ack, але ack - це портативний, автономний сценарій. Немає необхідності компілювати його або встановлювати його в системний каталог, такий як / usr / bin /. Після завантаження і розміщення в каталозі, вказаному в $ PATH (і його наборі бітів дозволу eXecute), він повинен працювати відразу. (Жодних привілеїв для судових або кореневих програм не потрібно, щоб приступити до роботи.)
JL

Це питання про те grep, чи не впевнений, що його використання для "реклами" ack(це справді чудовий інструмент) - гарна ідея ...
MonsieurDart

39
grep astring myfile -A 5 -B 5

Це призведе до "myfile" для "astring", і покаже 5 рядків до і після кожного матчу


19
"grep astring myfile -C 5" зробить те саме
Syed Siraj Uddin

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 --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, щоб отримати відповідь.
Chiel ten Brinke

1
@Yokai Крім того, що сказав Chiel ten Brinke, прийнята відповідь не згадує довгі варіанти
user3738870

10

Шукати "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- Показати NUM рядків до та після кожного матчу.

Також є такі параметри, як -A/ --after-contextі -B/ --before-context.

Інструмент побудований на основі регекс-двигуна Руста, що робить його дуже ефективним у великих даних.


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.