find and echo имена файлов только с найденным шаблоном

Вы можете получить вывод таким образом.

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

Это просто пример. Вы можете изменить его по-своему.

15
02.02.2017, 15:16
6 ответов
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 и производных).

25
27.01.2020, 19:49

Вы можете попробовать что-то вроде:

find . -name "*.py:" -exec grep -l {} \;

Это выполнение команды grep для каждого файла, обнаруженного командой find и ее стандартной функцией команды find

1
27.01.2020, 19:49

Используйте аргумент -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
1
27.01.2020, 19:49

Если вы используете GNU grep, вы можете использовать его -r или - рекурсивный Вариант , чтобы сделать эту простую находку за вас:

grep -r --include '*.py' -le "$regexp" ./ # for filenames only
grep -r --include '*.py' -He "$regexp" ./ # for filenames on each match

Вам понадобится только find , если вам нужны более сложные предикаты.

6
27.01.2020, 19:49

Вы можете указать 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
5
27.01.2020, 19:49

Существуют альтернативы 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) {
...

Я не могу показать вам здесь, но вывод аккуратно раскрашен. Я получаю имена файлов оливково-зеленым цветом, номера строк - золотисто-желтым, а совпадающий фрагмент в каждой строке - кроваво-красным. Впрочем, цвета можно настраивать.

1
27.01.2020, 19:49

Теги

Похожие вопросы