
Estou interessado em buscar recursivamente uma string em um diretório para um padrão e, em seguida, copiar o arquivo correspondente para um diretório de destino. Achei que poderia fazer algo como o seguinte, mas não parece fazer sentido com a ferramenta find do Linux:
find . -type f -exec grep -ilR "MY PATTERN" | xargs cp /dest/dir
Existe uma maneira melhor de fazer isso? Ou uma maneira que funcione seria um começo sólido.
Responder1
Faça man xargs
e olhe para a -I
bandeira.
find . -type f -exec grep -ilR "MY PATTERN" {} \; | xargs -I % cp % /dest/dir/
Além disso, find
espera um \;
ou +
após o -exec
sinalizador.
Responder2
Eu não acho que você precisa encontrar. Grepe recursivo:
grep -rl "MY PATTERN" .
Responder3
xargs
lê sua entrada padrão e as coloca no final do comando a ser executado. Como você escreveu, você acabaria executando
cp /dest/dir sourcefile1 sourcefile2 sourcefile3
que está ao contrário do que você deseja.
Você poderia usar a -I
opção para especificar um espaço reservado para xargs
, assim: xargs -I '{}' cp '{}' /dest/dir
.
Além disso, find
cuida da recursão, então você grep
não precisa do -R
.
Solução final:
find . -type f -exec grep -il "MY PATTERN" '{}' + | xargs -I '{}' cp '{}' /dest/dir
Responder4
Nenhum dos exemplos acima leva em consideração a possibilidade de grep
gerar -l
resultados duplicados (arquivos com o mesmo nome, mas em locais diferentes) e, portanto, o gancho find
de ' exec
sobrescrever arquivos no diretório de destino.
Uma tentativa de resolver isso:
$ tree foo
foo
├── bar
│ ├── baz
│ │ └── file
│ └── file
├── destdir
└── file
3 directories, 3 files
$ while read a; do mv $a foo/destdir/$(basename $a).$RANDOM; done < <(grep -rl content foo)
$ tree foo
foo
├── bar
│ └── baz
└── destdir
├── file.10171
├── file.10842
└── file.25404
3 directories, 3 files