Existe uma opção para grep -f MY_FILE
permitir que ele procure padrões retirados de um arquivo, em vez de serem especificados diretamente na linha de comando.
Existe uma opção para fazer algo semelhante com o find
comando e deixá-lo ler os padrões para pesquisar em um arquivo de entrada?
Responder1
find
não parece ter esses recursos integrados, mas você pode usar xargs
para construir vários find
comandos usando argumentos de um arquivo, como:
xargs -a patterns.txt -I% find Pictures/ -name %
onde patterns.txt
estaria uma lista de padrões adequados para o -name
filtro, um padrão por linha. Preste atenção para que você não tenha espaços iniciais/finais, pois eles seriam incluídos no padrão. Um exemplo:
*.jpg
2018-06-*
*foo*
unicorn.png
Observação:Embora esta resposta pareça bastante fácil e elegante, foi corretamente apontado nos comentários que ela tem algumas desvantagens:
O desempenho não é muito bom para pastas grandes ou muitos padrões, pois ele será executado
find
uma vez por padrão em seu arquivo, fazendo com que ele verifique repetidamente toda a pasta de pesquisa.Por causa disso, também se você tiver vários padrões que possam se sobrepor (como
*.jpg
e*foo*
), os arquivos que corresponderem a mais de um padrão aparecerão muitas vezes no resultado. Se você estiver apenas imprimindo os nomes de qualquer maneira, poderá canalizar a saídasort -u
para remover duplicatas, mas se, por exemplo, remover esses resultados ou executar qualquer-exec
comando neles, isso pode ser mais indesejável.Se alguma dessas desvantagens for um problema para o seu caso de uso, talvez seja melhor optar por uma das respostas alternativas.
Explicação do comando:
xargs
irá ler uma lista de argumentos e usá-los para construir e executar uma nova linha de comando.-a patterns.txt
diz para ler esse arquivo em vez da entrada padrão.-I%
diz para ele não simplesmente anexar os argumentos lidos ao final da linha de comando, mas para substituir o%
caractere na linha de comando que você forneceu por um argumento. Isto implica criar e executar um comando separado por argumento de entrada.find Pictures/ -name %
é a linha de comando na qual queremos inserir os argumentos, substituindo o%
. Você não precisa citar aqui, porquexargs
cuidará para que cada argumento inserido seja tratado como token único e não seja dividido por conta própria. É claro que você pode substituir oPictures/
pelo seu próprio diretório de pesquisa e também usar filtros diferentes e/ou mais filtros além de apenas-name
. Como usamos a opção de inserção, você também pode anexar ações como-exec ...
no final do comando.
Responder2
Você pode simplesmente criar uma regex a partir do conteúdo do seu arquivo usando paste -sd'|' bar
.
find ~/foo -regextype egrep -regex "^.*/($(paste -sd'|' bar))$"
A regex será"^.*/(a|b)$"
Responder3
Não muito recentemente, fiz umresponderque combina vários padrões usando -regex
sinalizador em find
. Com base nisso, podemos fazer um pequeno script ou função para fazer o mesmo trabalho, mas construir a lista de padrões a partir do arquivo.
#!/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\).*$"
O que isso faz:
- chamamos script como
findf.sh input.txt /etc
, onde o primeiro parâmetro posicional é o arquivo com padrões e o segundo é o diretório onde pesquisar. GNU find assume.
o diretório se o argumento do diretório for omitido, portanto$2
não é obrigatório. - A função
read_file
lê o arquivo de entrada que é o primeiro parâmetro posicional do script. Isso cria um padrão para-regex
a bandeira. - Esse padrão é repetido no bloco "principal" do script e salvo na
fp
variável, e isso é passado para ofind
comando.