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


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.