![Grep показывает имя файла и найденную строку](https://rvso.com/image/1127637/Grep%20%D0%BF%D0%BE%D0%BA%D0%B0%D0%B7%D1%8B%D0%B2%D0%B0%D0%B5%D1%82%20%D0%B8%D0%BC%D1%8F%20%D1%84%D0%B0%D0%B9%D0%BB%D0%B0%20%D0%B8%20%D0%BD%D0%B0%D0%B9%D0%B4%D0%B5%D0%BD%D0%BD%D1%83%D1%8E%20%D1%81%D1%82%D1%80%D0%BE%D0%BA%D1%83.png)
Мне нужна команда egrep, которая выводит список всех имен файлов, содержащих слова + какая строка найдена. Давайте представим себе такой сценарий:
Слова, которые мне нужно найти: apple
, watermelon
и banana
.
Что мне нужно: Я хочу перечислить все файлы, которые содержат любое из них (не обязательно, чтобы все они были в одном файле), и вывести, какое слово было найдено в файле. Пример результата поиска, который мне нужен:
./file1.txt:apple
./file1.txt:banana
./file2.txt:watermelon
./file5.txt:apple
Я помню, что видел grep
команду, которая отображается FILENAME:STRING
в результатах поиска, но не могу вспомнить, как она была сделана. Я попробовал:
egrep -lr 'apple|banana|watermelon' .
Но результаты поиска показали:
./file1.txt
./file2.txt
Хорошо, это помогает, но... в file1
, какое из слов оно нашло? Вот с какой проблемой я столкнулся .
решение1
Вы использовали -l
, что является противоположностью того, что вы хотели. Отman grep
:
-l, --files-with-matches
Suppress normal output; instead print the name of each input
file from which output would normally have been printed. The
scanning will stop on the first match. (-l is specified by
POSIX.)
Что вам нужно -H
:
-H, --with-filename
Print the file name for each match. This is the default when
there is more than one file to search.
Но это по умолчанию. Просто сделайте:
grep -Er 'apple|banana|watermelon' .
(Говорит -E
действовать grep
как egrep
.)
решение2
Как это сделать с помощью awk:
awk -v var1=apple -v var2=banana -v var3=watermelon '{ if($0~var1) {print FILENAME":"var1} ; if($0~var2) {print FILENAME":"var2} ; if($0~var3) {print FILENAME":"var3} }' *
По сути, объявляем 3 переменные и 3 оператора if для вывода имени файла и соответствующей переменной, которая была найдена.
РЕДАКТИРОВАТЬ
Более короткая версия:
awk '/watermelon/{ print FILENAME":watermelon" }; /banana/{print FILENAME":banana"}; /apple/ {print FILENAME":apple"}' *
Основная идея — найти /regular expression/
и выполнить код в фигурных скобках после него, если он найден (то есть вывести FILENAME и строку, которую мы нашли).
решение3
Вот команда, которую вы ищете:
grep -R "apple\|banana\|watermelon" <search_path>
-R прочитает все файлы в каждом каталогепуть_поиска, рекурсивно. Имя файла будет отображаться для каждого совпадения.
решение4
Следующая команда даст вам желаемый вывод (при использовании bash):
for x in apple banana watermelon ; do grep $x * ; done
В результате будут получены все строки, содержащие искомую строку.
Следующий код вернет вам только строку поиска:
for x in apple banana watermelon ; do grep -l $x * |xargs -I{} echo {}:$x; done