Как подсчитать количество строк в файле после совпадения grep?

14

Я пытаюсь подсчитать количество строк после проблемной строки в CSV-файле. Я знаю, что могу использовать grep -a #синтаксис для вывода # количества строк после того, как найдено совпадение. Меня интересует только фактическое количество строк. Я понимаю, что могу установить значение MAX_INT, передать его в файл и выполнить дополнительную обработку.

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

Какие-либо предложения?

NathanChristie
источник

Ответы:

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

Это будет работать с GNU grepи lseek()способным infile. Первый grepостановится на 1 -mуровне, а второй - -cкаждую строку, оставшуюся на входе.

Без GNU grep:

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

Конечно, grepвы можете использовать любые другие опции, кроме того, и останавливаться на одном матче совсем не обязательно.

mikeserv
источник
Оба из них также печатают строку, а второй на печатает до первого совпадения, а затем 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
это не codegolf, можете ли вы дать подробности (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 '$='

Удаляет все строки перед строкой, а затем следующая команда считает строки в новом файле.

123
источник
3

Это должно удалить все строки до (и включая) проблемной, а затем подсчитать оставшиеся строки:

sed '1,/problem/d' data.txt | wc -l
гость
источник
1
(при условии, что «проблема» не в первой строке)
Стефан Шазелас