Поиск нескольких шаблонов в файле с помощью команды find [duplicate]

Там - это возможность использовать grep -f MY_FILE , чтобы разрешить поиск шаблонов, взятых из файла, вместо того, чтобы указывать их непосредственно в командной строке.

Есть ли возможность сделать что-то подобное с командой find и позволить ей читать шаблоны для поиска из входного файла?

0
задан 14 June 2018 в 00:58

3 ответа

find кажется, не встраивает такие возможности, но можно использовать xargs создать несколько find команды с помощью аргументов из файла, как:

xargs -a patterns.txt -I% find Pictures/ -name %

где patterns.txt был бы список шаблонов, подходящих для -name фильтр, один шаблон на строку. Обратите внимание, что у Вас нет продвижения/конечных пробелов там, поскольку они были бы включены в шаблон. Пример:

*.jpg
2018-06-*
*foo*
unicorn.png

Примечание: В то время как этот ответ выглядит довольно легким и изящным, на него правильно указали в комментариях, что он имеет несколько оборотных сторон:

Производительность не является слишком большой для больших папок или многих шаблонов, когда она будет работать find однажды на шаблон в Вашем файле, заставляя это неоднократно просканировать целую поисковую папку.

Из-за этого также если у Вас есть несколько шаблонов, которые могли бы потенциально наложиться (как *.jpg и *foo*), файлы, соответствующие больше чем одному шаблону, будут появляться что много раз в результате. Если Вы только печатаете имена так или иначе, Вы могли бы передать вывод по каналу через sort -u чтобы удалить дубликаты, но если Вы, например, удалить те результаты или выполняют кого-либо -exec команды на них, это может быть более нежелательно.

Если какая-либо из этих оборотных сторон является проблемой для Вашего варианта использования, возможно, лучше пойдите для одного из альтернативных ответов.

Объяснение команды:

  • xargs будет читать список аргументов и использовать их, чтобы создать и выполнить новую командную строку.
  • -a patterns.txt говорит этому читать из того файла вместо стандартного входа.
  • -I% говорит, что это к не просто добавляет аргументы, которые это считало в конец командной строки, но заменять % символ в командной строке Вы предоставили один аргумент. Это подразумевает создание и выполнение одной отдельной команды на входной параметр.
  • find Pictures/ -name % командная строка, в которую мы хотим вставить аргументы, заменяя %. Вам не нужно заключение в кавычки здесь, потому что xargs будет заботиться, что каждый аргумент это, вставки будут рассматривать как единственный маркер и не разделяться самостоятельно. Можно, конечно, заменить Pictures/ с Вашим собственным поисковым каталогом и также используют другое и/или больше фильтров кроме просто -name. Поскольку мы используем опцию вставки, можно также добавить действия как -exec ... в конец команды.
4
ответ дан 29 October 2019 в 03:00

Вы можете просто создать регулярное выражение из содержимого вашего файла, используя paste -sd'|' bar.

find ~/foo -regextype egrep -regex "^.*/($(paste -sd'|' bar))$"

Регулярное выражение будет "^.*/(a|b)$"

4
ответ дан 29 October 2019 в 03:00

Не так давно я сделал ответ , который объединяет несколько шаблонов с использованием флага -regex в find. Исходя из этого, мы можем создать небольшой скрипт или функцию для выполнения той же работы, но составить список шаблонов из файла.

#!/bin/bash

read_file(){
    local full_pattern=""
    while IFS= read -r pattern; do
        if [ -z "$full_pattern"  ];then
            full_pattern="$pattern"
            continue
        fi
        full_pattern="$full_pattern\|$pattern"
    done < "$1"
    echo "$full_pattern"
}

fp=$(read_file "$1" )
find "$2" -type f -regex ".*\($fp\).*$" 

Что это делает:

  • мы называем скрипт как findf.sh input.txt /etc, где первый позиционный параметр - это файл с шаблонами, а второй - каталог для поиска. GNU find предполагает наличие каталога ., если аргумент directory опущен, поэтому $2 не требуется.
  • Функция read_file считывает входной файл, который является первым позиционным параметром, в сценарий. Это создает шаблон для флага -regex.
  • Этот паттерн возвращается в «основной» блок скрипта и сохраняется в переменную fp, что передается в команду find.
2
ответ дан 29 October 2019 в 03:00

Другие вопросы по тегам:

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