Використовуйте grep, щоб повідомити про відповідні лише номери рядків


105

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

Однак, здається, не існує способу друкувати номер рядка ( grep -n), а не збіг чи саму лінію.

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


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

Відповіді:


156

спробуйте:

grep -n "text to find" file.ext | cut -f1 -d:

1
На моїй машині це тільки друк відповідних файлів без номерів рядків (тому, якщо у мене є 3 збіги всередині файлу, він друкується лише один раз), що все ще дуже корисно ...
Mario Awad

3
@MarioAwad, вам слід маніпулювати -fпарам. Для мене це було -f2. (Знай, це старі речі, але я думаю, що це може допомогти бідним душам)
Emil Sierżęga

дякую за прекрасний старий сценарій Unix adhoc shell. це показує, що гнучкі інструменти варті своєї складності та кривої навчання!
Олексій

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 | вирізати, або в будь-який час, коли ви хочете взяти греп-вихід і маніпулювати ним.


2
Використовує один процес (який мав більше значення в минулому, але все-таки), і досить простий для розуміння для початківців-початківців!
bgStack15

NRпрацює також, коли вивчається лише один файл, як у цьому випадку.
Марк Рід

Просто геніально! Це так швидко!
Гтодоров

34

Усі ці відповіді потребують grep для генерації цілих відповідних ліній, а потім передайте їх іншій програмі. Якщо ваші лінії дуже довгі, може бути ефективніше використовувати просто sed для виведення номерів рядків:

sed -n '/pattern/=' filename

2

Версія Bash

    lineno=$(grep -n "pattern" filename)
    lineno=${lineno%%:*}

1
А що станеться, якщо більше одного рядка відповідає цьому шаблону?
izabera

@izabera додати | хвіст -1
Дієго

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:


Це працює, якщо ви хочете узгодити текст, але у випадку, якщо номер рядка - це те, про що вимагала ОП.
AJP

0

Для підрахунку кількості рядків, відповідних шаблону:

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

Для вилучення узгодженого малюнка

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

Відображення номерів рядків, за якими узор був узгоджений

grep -n "pattern" file.ext | cut -f1 -d:

2
1-й повинен бути просто "grep -c" Шаблон "in_file.ext". 2-го повинно бути "grep -o" Шаблон 'in_file.ext ". Не потрібно залучати sed або wc.
thelogix

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