Відобразити ім'я файлу перед відповідним рядком


282

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


2
повідомте про свою греп-версіюgrep --version
Кент

3
kent, grep --versionце команда, яку слід використовувати, щоб знати версію grep? Якщо так, то його не працює. Не вдалося знайти будь-яку іншу команду, щоб знати grep-версію.
Вівек

2
гарне запитання, але "версія Os" - заплутаний приклад назви файлу
HaveAGuess

1
ОС і версія тут не мають значення.
MD XF

grep 'pattern' *
користувач0

Відповіді:


430

Спробуйте цей маленький трюк, щоб придумати, grepщо він має справу з декількома файлами, щоб він відображав ім'я файлу:

grep 'pattern' file /dev/null

Щоб також отримати номер рядка:

grep -n 'pattern' file /dev/null

6
Так, це спрацювало. Скажіть, будь ласка, яке значення додавання /dev/nullв цю команду?
Вівек

55
Якщо grepпостачається кілька імен файлів, вони автоматично відображатимуть імена файлів перед матчем, але ім'я файлу залишатиметься у випадку одного вхідного файлу. Використовуючи /dev/nullяк додатковий вхідний файл, grep"думає", що він працює з декількома файлами, але / dev / null звичайно порожній, тому він не відображатиметься у списку матчів ..
Scrutinizer

32
використання / dev / null - розумний трюк, але я вважаю, що пропозиція нижче прапора -H є кращою відповіддю.
JohnQ

22
Гаразд, але -Hопція grep не є частиною POSIX, а використовувана ОС - Solaris 10, де ні стандартна, ні POSIX-версія версія grep не мають такої -Hможливості.
Scrutinizer

4
Це важливо, якщо ви використовуєте grep з find, як-от find . -name foo -exec grep pattern {} \;- якщо припустити, що велика кількість файлів, названих fooу вашому підкаталозі, findвсе-таки передає grepодин файл для роботи за один раз. /dev/nullТрюк , здається, працює у всіх Linux / OSX аромати , які я пробував, так що престижність! Примітка. Я думаю, що -Hце чистіше, але, як зазначено нижче, воно може не підтримуватися у вашій версії grep.
Джон V

296

Якщо у вас є варіанти -Hта -nдоступні ( man grepце ваш друг):

$ cat file
foo
bar
foobar

$ grep -H foo file
file:foo
file:foobar

$ grep -Hn foo file
file:1:foo
file:3:foobar

Параметри:

-H, --з ім'ям файлу

Роздрукуйте ім’я файлу для кожної відповідності. Це за замовчуванням, коли для пошуку більше одного файлу.

-n, - рядок-число

Префікс кожного рядка виводу з номером рядка на основі 1 у вхідному файлі. (-n визначається POSIX.)

-Hце розширення GNU, але -nце визначається POSIX


3
Ні, -Hтут не підтримується.
Вівек

1
Підтримується, але він завжди дає grep: file: Немає такого файлу чи каталогу
pal4life

2
працює на ubuntu -H та -n. Напевно, з усіма новішими версіями * nix
tgkprog

1
Я багато років боровся з цим, не думаючи, що існують ці варіанти!
GreenSaguaro

45

Ніякого фокусу не потрібно.

grep --with-filename 'pattern' file

З номерами рядків:

grep -n --with-filename 'pattern' file

3
@codeforester Я не знаю жодного іншого grep, тому я не знаю.
MD XF

2
Класно! це працювало для Linux. якщо ви використовуєте mac, можна встановити coreutils з варінням. І пам’ятайте, додайте PATH = "/ usr / local / opt / coreutils / libexec / gnubin: $ PATH" у свій .bashrc
zw963

2
Це (також) працювало в MinGW (1.0.17, я думаю).
Пітер Мортенсен

Для мене це працює із вбудованою Mac grep (2.5.1-FreeBSD). Але використовувати альтернативний греп від Homebrew, інший спосіб - запустити, brew install grepа потім просто використовувати ggrep. Не потрібно змінювати PATH.
wonderlr

5

Як щодо цього, чого мені вдалося частково подякувати цій посаді.

Ви хочете знайти декілька файлів, скажімо, журнали з різними іменами, але зразком (наприклад filename=logfile.DATE), всередині декількох каталогів з малюнком (наприклад /logsapp1, /logsapp2). Кожен файл має шаблон, який ви хочете зібрати (наприклад "init time"), і ви хочете мати "init time"кожен файл, але знаючи, до якого файлу він належить.

find ./logsapp* -name logfile* | xargs -I{} grep "init time" {} \dev\null | tee outputfilename.txt

Тоді outputfilename.txtбуло б щось подібне

./logsapp1/logfile.22102015: init time: 10ms
./logsapp1/logfile.21102015: init time: 15ms
./logsapp2/logfile.21102015: init time: 17ms
./logsapp2/logfile.22102015: init time: 11ms

В загальному

find ./path_pattern/to_files* -name filename_pattern* | xargs -I{} grep "grep_pattern" {} \dev\null | tee outfilename.txt

Пояснення:

find команда буде шукати назви файлів на основі шаблону

то труба xargs -I{}буде перенаправляти findвихід на{}

який буде входом для grep ""pattern" {}

Тоді хитрість зробити grepвідображення імен файлів\dev\null

і, нарешті, запишіть вихід у файл tee outputfile.txt

Це працювало для мене у grepверсії 9.0.5 збірки 1989 року.


3
Або просто використовуючи знахідкуfind ./path_pattern/to_files -type f -name "files*.log" -exec grep -Hn pattern {} \;
Мартін

1

Це незначна модифікація попереднього рішення. Мій приклад шукає перенаправлення stderr у скриптах bash: grep '2>' $(find . -name "*.bash")


-7
grep 'search this' *.txt

працював над тим, щоб шукати всі файли .txt (звичайно, введіть власне значення пошуку).

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