Используйте grep, чтобы сообщить только номера строк

106

У меня есть файл, который, возможно, содержит неправильное форматирование (в данном случае наличие шаблона \\backslash). Я хотел бы использовать grepдля возврата только номеров строк, в которых это происходит (например, совпадение было здесь, перейдите к строке № x и исправьте ее).

Однако, похоже, нет способа распечатать номер строки ( grep -n), а не совпадение или саму строку.

Я могу использовать другое регулярное выражение для извлечения номеров строк, но я хочу убедиться, что grep не сможет этого сделать самостоятельно. grep -noподходит ближе всего, я думаю, но все же отображает совпадение.

Нил
источник
1
Самый полезный для меня ответ был в вопросе grep -no:! Это сделало то, что я пришел сюда, чтобы попробовать и сделать! (то есть не печатать строку, которая иногда бывает очень длинной, например, в уменьшенных исходных файлах javascript.)
LondonRob

Ответы:

156

пытаться:

grep -n "text to find" file.ext | cut -f1 -d:
love_me_some_linux
источник
1
На моей машине это печатает только совпадающие файлы без номеров строк (поэтому, если у меня есть 3 совпадения внутри файла, он печатается только один раз), что все еще очень полезно ...
Марио Авад
3
@MarioAwad, вы должны изменить -fпараметр. Для меня это было -f2. (Знайте, что это старый материал, но я думаю, что он может помочь некоторым бедным душам)
Эмиль Серженга
Спасибо за прекрасный старый сценарий adhoc оболочки unix. это показывает, что гибкие инструменты стоят своей сложности и времени на обучение!
Alex
12
grep -n "text to find" file.ext | cut -f1,2 -d:показывает имя файла и номер строки.
Jondlm
2
@jondim показывает имя файла, только если ищется более одного файла; вам нужно добавить, -Hчтобы заставить его показывать имя файла, когда есть только один файл. И наоборот, вы всегда можете использовать, -hчтобы запретить вывод имени файла, независимо от того, сколько файлов вы используете.
Марк Рид
45

Если вы готовы использовать AWK:

awk '/textstring/ {print FNR}' textfile

В этом случае FNR - это номер строки. AWK - отличный инструмент, когда вы смотрите на grep | cut или когда хотите получить вывод grep и манипулировать им.

блистательный мастер
источник
2
Использует один процесс (который имел большее значение в прошлом, но все же), и достаточно простой для понимания для начинающих awk!
bgStack15
NRработает также, когда проверяется только один файл, как в этом случае.
Марк Рид
Просто гениально! Это так быстро!
Г.Тодоров
34

Все эти ответы требуют, чтобы grep сгенерировал все совпадающие строки, а затем перенаправил их в другую программу. Если ваши строки очень длинные, может быть более эффективным использовать только sed для вывода номеров строк:

sed -n '/pattern/=' filename
индивидуалист
источник
2

Версия Bash

    lineno=$(grep -n "pattern" filename)
    lineno=${lineno%%:*}
индивидуалист
источник
1
А что произойдет, если этому шаблону соответствует более одной строки?
izabera 05
@izabera add | tail -1
Diego
1

Я рекомендую ответы с указанием sedи awkтолько для получения номера строки, а не grepдля получения всей совпадающей строки с последующим удалением ее из вывода с помощью cutили другого инструмента. Для полноты вы также можете использовать Perl:

perl -nE '/pattern/ && say $.' filename

или Рубин:

ruby -ne 'puts $. if /pattern/' filename
Марк Рид
источник
0

Вам понадобится второе поле после двоеточия, а не первое.

grep -n "text to find" file.txt | cut -f2 -d:

Крис
источник
Это работает, если вы хотите сопоставить текст, но в случае, если номер строки - это то, о чем просил OP.
AJP
0

Чтобы подсчитать количество строк, соответствующих шаблону:

grep -n "Pattern" in_file.ext | wc -l 

Чтобы извлечь совпавший шаблон

sed -n '/pattern/p' file.est

Для отображения номеров строк, в которых был найден образец

grep -n "pattern" file.ext | cut -f1 -d:
JstRoRR
источник
2
1-й должен быть просто «grep -c 'Pattern' in_file.ext». Второй должен быть «grep -o 'Pattern' in_file.ext». Не нужно задействовать sed или wc.
thelogix 01
0

используя только grep :

grep -n "text to find" file.ext | grep -Po '^[^:]+'

Микаэль Леви
источник