Вы можете получить вывод таким образом.
week="" week=`date` echo $week >> results.xls
find /home/user/admin/old/ -mtime -7 | wc -l >> results.xls
# cat results.xls
Thu Oct 27 14:16:29 IST 2016
0
2
Это просто пример. Вы можете изменить его по-своему.
find . -name '*.py' -exec grep something {} \; -print
выведет имя файла после совпадающих строк.
find . -name '*.py' -exec grep something /dev/null {} +
выводит имя файла перед каждой совпадающей строкой (мы добавляем /dev/null
для случая, когда есть только один совпадающий файл, поскольку grep
не выводит имя файла, если ему передан только один файл для поиска. В GNU-реализации grep
есть опция -H
для этого в качестве альтернативы).
find . -name '*.py' -exec grep -l something {} +
выведет только имена файлов, в которых есть хотя бы одна совпадающая строка.
Чтобы вывести имя файла перед совпадающими строками, можно использовать awk:
find . -name '*.py' -exec awk '
FNR == 1 {filename_printed = 0}
/something/ {
if (!filename_printed) {
print FILENAME
filename_printed = 1
}
print
}' {} +
Или вызвать grep
дважды для каждого файла - хотя это будет менее эффективно, поскольку для каждого файла будет выполняться как минимум одна команда grep
и до двух (и дважды считываться содержимое файла):
find . -name '*.py' -exec grep -l something {} \; \
-exec grep something {} \;
В любом случае, вы не хотите циклически просматривать вывод find
подобным образом и не забывайте заключать свои переменные в кавычки.
Если вы хотите использовать shell-цикл, средствами GNU:
find . -name '*.py' -exec grep -l --null something {} + |
xargs -r0 sh -c '
for file do
printf "%s\n" "$file"
grep something < "$file"
done' sh
(также работает на FreeBSD и производных).
Вы можете попробовать что-то вроде:
find . -name "*.py:" -exec grep -l {} \;
Это выполнение команды grep для каждого файла, обнаруженного командой find и ее стандартной функцией команды find
Используйте аргумент -l
.
for file in `find . -name "*.py"`; do grep -l something $file && grep something $file; done
Другой вариант использования findish:
for file in $(find . -name '*.py' -exec grep -l something '{}' +); do echo "$file"; grep something $file; done
Если вы используете GNU grep, вы можете использовать его -r
или - рекурсивный Вариант
, чтобы сделать эту простую находку за вас:
grep -r --include '*.py' -le "$regexp" ./ # for filenames only
grep -r --include '*.py' -He "$regexp" ./ # for filenames on each match
Вам понадобится только find
, если вам нужны более сложные предикаты.
Вы можете указать grep включить имя файла в вывод. Таким образом, если есть совпадение, оно будет показано на консоли; если в файле нет совпадений, для этого файла не будет напечатано ни одной строки.
find . -name "*.py" | xargs grep -n -H something
Из man grep
:
-H Always print filename headers with output lines
-n, --line-number
Each output line is preceded by its relative line number in the file, starting at line 1. The line number counter is reset for each file processed.
This option is ignored if -c, -L, -l, or -q is specified.
Если ваши файлы могут иметь имена с пробелами в них, вы должны переключить канал, чтобы использовать символы NUL в качестве разделителя. Полная команда теперь будет выглядеть так:
find . -name "*.py" -print0 | xargs -0 grep -n -H something
Существуют альтернативы grep
, которые по умолчанию выводят результаты в нужном вам формате. Две самые популярные, которые я знаю, это ag
(он же "серебряный искатель") и ack
. ag
рекламируется как более быстрая альтернатива ack
.
$ ag '^\w+\s*\w+\(' ~/build/i3/src
build/i3/src/display_version.c
58:void display_running_version(void) {
build/i3/src/load_layout.c
42:static TAILQ_HEAD(focus_mappings_head, focus_mapping) focus_mappings =
518:json_content_t json_determine_content(const char *filename) {
575:void tree_append_json(Con *con, const char *filename, char **errormsg) {
build/i3/src/x.c
64:CIRCLEQ_HEAD(state_head, con_state) state_head =
67:CIRCLEQ_HEAD(old_state_head, con_state) old_state_head =
70:TAILQ_HEAD(initial_mapping_head, con_state) initial_mapping_head =
97:void x_con_init(Con *con, uint16_t depth) {
...
Я не могу показать вам здесь, но вывод аккуратно раскрашен. Я получаю имена файлов оливково-зеленым цветом, номера строк - золотисто-желтым, а совпадающий фрагмент в каждой строке - кроваво-красным. Впрочем, цвета можно настраивать.