Como canalizar corretamente a localização com grep e cp neste caso de uso

Como canalizar corretamente a localização com grep e cp neste caso de uso

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 xargse olhe para a -Ibandeira.

find . -type f -exec grep -ilR "MY PATTERN" {} \; | xargs -I % cp % /dest/dir/

Além disso, findespera um \;ou +após o -execsinalizador.

Responder2

Eu não acho que você precisa encontrar. Grepe recursivo:

grep -rl "MY PATTERN" .

Responder3

xargslê 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 -Iopção para especificar um espaço reservado para xargs, assim: xargs -I '{}' cp '{}' /dest/dir.

Além disso, findcuida da recursão, então você grepnã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 grepgerar -lresultados duplicados (arquivos com o mesmo nome, mas em locais diferentes) e, portanto, o gancho findde ' execsobrescrever 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

informação relacionada