Отримання останнього збігу у файлі за допомогою grep


58

Який найкращий спосіб отримати лише остаточну відповідність регулярного виразу у файлі за допомогою grep?

Крім того, чи можна починати зіткнення з кінця файлу замість початку та зупинятися, коли він знайде першу відповідність?

Відповіді:


85

Ви можете спробувати

grep pattern file | tail -1

або

tac file | grep pattern | head -1

або

tac file | grep -m1 pattern

20
tac file | grep -m 1 pattern
Денніс Вільямсон

1
З доданим обмеженням, що я хотів отримати номер рядка ( grep -n) у фактичному файлі, я думаю, що tacцього треба було уникнути, якщо тільки я не хотів зробити якесь віднімання wc -l. Інакше tacз grep -m1має багато сенсу.
Нік Меррілл

1
Я хотів би побачити більш ефективну версію, ніж ця, оскільки я намагаюся шукати файл у 20 Гб.
Jeff

Відповідь @DennisWilliamson набагато краща, оскільки grepперестане працювати після першого матчу. без -m 1, grepспочатку знайде всі відповідні шаблони у файлі , потім headпокаже лише перший - набагато менш ефективний. Деннісе, будь ласка, розглядайте питання про це окремою відповіддю!
gilad mayani

1

Для тих, хто працює з величезними текстовими файлами в Unix / Linux / Mac / Cygwin. Якщо ви використовуєте Windows, ознайомтесь із інструментами Linux у Windows: https://stackoverflow.com/questions/3519738/what-is-the-best-way-to-use-linux-utilities-under-windows .

Можна дотримуватися цього робочого процесу, щоб мати хороші показники:

  1. компрес з gzip
  2. використовувати zindex (на github: https://github.com/mattgodbolt/zindex ), щоб індексувати файл відповідним ключем
  3. запитувати індексований файл із zqпакету.

Цитата з її програми github readme:

Створення індексу

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

За замовчуванням zindex створює індекс file.gz.zindex, коли його запитують до індексу file.gz.

Приклад:

створити індекс на рядках, що відповідають числовому регулярному виразу. Група захоплення вказує ту частину, яку потрібно проіндексувати, а параметри показують, що кожен рядок має унікальний числовий індекс.

$ zindex file.gz --regex 'id:([0-9]+)' --numeric --unique

Приклад: створіть індекс у другому полі файлу CSV:

$ zindex file.gz --delimiter , --field 2 

Приклад:

створити індекс у полі JSON orderId.id в будь-якому з елементів масиву дій кореня документа (потрібен jq). Запит jq створює масив усіх orderId.ids, потім з'єднує їх з пробілом, щоб забезпечити кожен окремий рядок, перекладений на jq, створює єдину лінію виводу, з декількома збігами, розділеними пробілами (що є роздільником за замовчуванням).

$ zindex file.gz --pipe "jq --raw-output --unbuffered '[.actions[].orderId.id] | join(\" \")'" 

Запит на індекс

Програма zq використовується для запиту індексу. Дано ім'я стисненого файлу та список запитів. Наприклад:

$ zq file.gz 1023 4443 554 

Можна також виводити за номером рядка, щоб надрукувати рядки 1 і 1000 з файлу:

$ zq file.gz --line 1 1000

1

Я завжди використовую кота (але це робить його трохи довшим): cat file | grep pattern | tail -1

Я б звинувачував мого викладача курсу linux в коледжі, який любить котів :))))

- Вам не доведеться спочатку копіювати файл перед тим, як отримати його. grep pattern file | tail -1і є також більш ефективним.


6
Це лише перша частина відповіді Какемокса, крім гіршої.
серпень

Це працює, але робить непотрібні кроки. Для легкого використання це рішення чудово працює, але воно не працює добре. Причина полягає в тому, що вам не потрібно catфайл і передавати його grep. Ви можете grepшукати файл безпосередньо через grep pattern file(а потім використовувати tailдля повернення останнього результату), як у відповіді Cakemox.
jvriesem
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.