como usar grep e mv juntos em um diretório no shell?

0

como você grep o conteúdo de todos os arquivos em um diretório para "TEST", em seguida, mover os arquivos para um diretório diferente (como o diretório home.)?

    
por john 06.03.2014 / 03:56

2 respostas

1

Apenas outra alternativa (isso requer algumas extensões específicas do GNU, já que você marcou a pergunta "Unix", pode não se encaixar):

grep -lZd skip TEST SOURCE/* | xargs -0I{} mv -i {} DEST
  • grep -l

    imprime nomes de arquivos correspondentes em vez da saída normal.

  • grep -Z

    fornece uma saída nula separada por byte, o que é uma aposta segura na manipulação de nomes estranhos de arquivos através de pipes.

  • grep -d skip

    define a ação skip para diretórios encontrados entre os argumentos de entrada.

    Isso não é realmente necessário; apenas evita o aviso grep: SOURCE/DIR: Is a directory ao encontrar diretórios. Se você quiser leitura recursiva de arquivos em diretórios, use a ação recurse , ou até menor, apenas a opção -r equivalente (veja também o ponto abaixo).

  • SOURCE/*

    corresponde a todos os arquivos no diretório SOURCE usando shell globbing . Arquivos ocultos são por padrão não correspondidos; isso pode ser alterado definindo shopt -s dotglob no Bash antes do comando grep ser emitido.

    Pode-se ficar tentado a adicionar SOURCE/.* aos argumentos de entrada, mas isso terá talvez consequências inesperadas se usado com -r (já que também combinamos . e .. ).

    Se a correspondência recursiva for desejada, use apenas -r SOURCE sem globbing de arquivo como o argumento de entrada, o que inclui arquivos ocultos na estrutura de diretórios.

  • xargs -0

    interpreta a entrada como nula separada.

  • xargs -I{}

    define {} como um marcador para o argumento de entrada.

  • mv -i

    torna a jogada interativa de acordo com a sugestão de Dennis, para evitar erros.

Para testar esse padrão (ou comandos em geral), uma técnica útil é inserir echo antes do comando real para ver quais comandos devem ser executados, ou seja, alterar mv para echo mv .

    
por 06.03.2014 / 09:31
1

Você pode combinar grep e encontrar para esta tarefa:

find SOURCE -maxdepth 1 -type f -exec grep -q TEST {} \; -exec mv -i {} DEST \;

Como funciona

  • find SOURCE -maxdepth 1 -type f encontra todos os arquivos ( -type f ) no diretório SOURCE .

    Se você quiser incluir arquivos em subdiretórios, basta remover -maxdepth 1 .

  • -exec grep -q TEST {} \; greps os arquivos, um por um, para a string TEST . Aqui, {} é o arquivo que está sendo processado no momento.

    A opção -q torna o grep "silencioso", ou seja, não produzirá nada. A instrução -exec será verdadeira se grep for bem-sucedida, ou seja, encontrar a string.

  • -exec mv -i {} DEST \; move um arquivo contendo a string TEST para o diretório DEST .

    A opção -i torna mv "interativa", ou seja, ele avisa antes de sobrescrever outros arquivos.

por 06.03.2014 / 04:12