Comando Grep para encontrar arquivos que contenham texto e movê-los


15

Eu sou capaz de localizar arquivos em uma pasta que contém uma sequência de texto específica usando este comando:

grep -lir 'string' ~/directory/*

Como movo os arquivos que aparecem no resultado acima para outro local?


Aqui está. grep -i -Z -r -l 'string' . | xargs -I{} mv {} ./folder_name
Alan Dong

Respostas:


10

Como sempre, cuidado com grep -r. -rnão é uma opção padrão e, em algumas implementações, como todas as versões muito recentes do GNU grep, segue links simbólicos ao descer a árvore de diretórios, o que geralmente não é o que você deseja e pode ter implicações graves se, por exemplo, houver um link simbólico para "/ "em algum lugar na árvore de diretórios.

Na filosofia do Unix, você usa um comando para procurar arquivos em diretórios e outro para examinar seu conteúdo.

Usando ferramentas GNU, eu faria:

xargs -r0 --arg-file <(find . -type f -exec grep -lZi string {} +
  ) mv -i --target-directory /dest/dir

Mas, mesmo assim, tenha cuidado com as condições de corrida e possíveis problemas de segurança se você o executar como um usuário em um diretório gravável por outro usuário.


isso me dá erro find: `grep 'finalizado pelo sinal 13. alguma idéia do que está errado?
Reena Parekh

@ReenaParekh, isso seria um SIGPIPE. Isso só aconteceria se fosse xargsencerrado antes da leitura até o final de seu arquivo arg, o que não deveria acontecer, a menos que o xargs se matasse ou falhasse por qualquer motivo, nesse caso, espero que você também veja um erro sobre isso.
Stéphane Chazelas

15

Use xargsem conjunto com mva terceira sintaxe:mv [OPTION]... -t DIRECTORY SOURCE...

grep -lir 'string' ~/directory/* | xargs mv -t DEST

Cuidado com arquivos que contêm caracteres especiais (espaços, aspas). Se esse for o seu caso, filtrar a lista com sed(adicionar aspas aos nomes de arquivos com s/^/'/;s/$/'/) pode ajudar, mas você precisa ter certeza de que essas aspas não aparecerão nos nomes dos arquivos. O GNU greptem a opção -Z/ --nullpara encerrar nomes de arquivos NUL.

Uma alternativa para a terceira sintaxe para mvé usar xargscom a sequência de marcações ( -I).

Outra opção é a substituição de comandos - $( )ou backticks ``(no bash), como mencionado na resposta de ire_and_curses.


3
gnu grep suporta uma bandeira Z para nomes de arquivos separados pelo carácter zero byte, que, quando usado em conjunto com a -0 bandeira para xargs, pode obter em torno dos caracteres especiais emitir você menciona
Iruvar

@ChandraRavoori obrigado, atualizei a resposta.
Peterph


1

Usando apenas os recursos especificados no POSIX e não fazendo suposições sobre os nomes de arquivos:

find ~/directory -type f -exec grep -qiF 'string' {} \; -exec mv {} /path/to/dest \;

Notas:

Você disse "string" e não "pattern", portanto a opção -F(pesquisa de string fixa) grepparece apropriada.

Se o diretório de destino estiver em qualquer lugar dentro do diretório de pesquisa, você poderá ter algumas condições desagradáveis ​​de corrida.

Especificações POSIX para grep

Especificações POSIX para find


Esta pode ser a melhor solução para Macos / BSD
Ali

0

Usando o GNU paralelo :

grep -i -Z -r -l 'string' . | parallel 'mv {} destination/{}'

ht / @ lin-dong por sua resposta original com xargs.


Teria sido bom se você tivesse creditado a resposta de @ lindong nos comentários de mais de um ano atrás.
roaima 01/08/16

0

Suponha que você tenha o diretório de destino como 'externo' e precise mover todos os arquivos XLS, tente o comando abaixo

sudo mv find /var/log/ -type f -name "*.xls"/ externo /

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.