Як я можу підрахувати кількість рядків у файлі після збігу grep?


14

Я намагаюся підрахувати кількість рядків після проблемного рядка у файлі csv. Я усвідомлюю, що можу використовувати grep -a #синтаксис для виведення # кількості рядків після того, як знайдено збіг. Мене цікавить лише фактична кількість рядків. Я розумію, що міг би встановити номер на MAX_INT, передати його у файл та зробити ще одну обробку.

Я шукаю лаконічний одноколісний лайнер, щоб просто розповісти мені про кількість.

Будь-які пропозиції?

Відповіді:


15
{ grep -m1 match; grep -c ''; } <file

Це буде працювати з GNU grepта lseek()можливою інформацією. Перший grepзупиниться на 1 -mатч, а другий -cвідкине кожен рядок, що залишився на вході.

Без GNU grep:

{ sed '/match/q'; grep -c ''; } <file

Звичайно, grepкрім того, ви можете використовувати будь-який / всі інші його варіанти, окрім того, і зупинятися на одному поєдинку зовсім не потрібно.


Обидва вони також друкують рядок, а другий друкує до першого матчу, а потім 0 ​​для мене?
123,

@ User112638726 - ви, звичайно, можете скинути роздруківку першого матчу grep -m1 match >/dev/null. І друга ваша проблема - це GNU sed- він не скидає вхідне зміщення за специфікацією. Ви повинні використовувати -uw / GNU - що не завжди бажано. Я міг би бути зрозумілішим, але моє припущення було, що GNU grepта GNU sedбудуть надходити парами. Я думаю, також grep -qm1міг би працювати над скороченням /dev/nullпереадресації - але GNU grepробить дивні речі, -qне знаючи, як вони працюють разом.
mikeserv

1
Гарна відповідь - дійсно демонструє силу командних угруповань. Я точно не знаю, але я б припустив wc -l, що це трохи дешевше, ніж grep -c ''.
Цифрова травма

1
@DigitalTrauma - Так, я вважав це (ретроспективно) , але я вже написав це, і він майже римувався, тож я зрозумів, що відпущу досить добре в спокої. І все одно, ви це теж сказали, тож я зараз легко сплю.
mikeserv

9

Ось один із способів.

$ cat foo
aaa
bbb
ccc
ddd
eee
fff
$ awk '/^ddd/{a=FNR}END{print FNR-a}' foo
2
$

4
це не кодогольф, ви можете дати деталі (FNR, END і так далі)?
Архемар

3
Звичайно. awk використовує FNR для ідентифікації номера вхідного запису. END - код, виконаний після досягнення кінця файлу. Тож коли знайдено збіг, записується поточний номер рекорду. Після досягнення кінця файлу це число віднімається від загальної кількості рядків у файлі.
Стів

1
Можемо також просто використовувати NR, оскільки це один файл.
123,

6

Ще один спосіб - використання dcє трохи езотеричним, але, здається, тут добре працює:

sed -n '/problem/=;$=' prob.txt | dc -e '??r-p'

sedшукає prob.txt"проблему" та останній рядок і використовує =команду для виведення номера рядка обох.

dc читає ці два значення на стек, перевертає їх, віднімає та друкує різницю.


5

Цілком з sed (хоч і дві команди з трубою)

sed '/ddd/,$!d' file | sed -n '$='

Видаляє весь рядок перед рядком, а потім наступна команда рахує рядки в новому файлі.


3

Слід видалити всі рядки до проблемного (включаючи), а потім підрахувати решту рядків:

sed '1,/problem/d' data.txt | wc -l

1
(якщо припустити, що "проблема" не в першому рядку)
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.