como mover todos os arquivos de um pipe para um diretório?

1

Eu executei um comando de arquivo em todos os elementos no diretório do meu Desktop:

~/Desktop > file * 

então eu usei todas as linhas que possuem a string "image" na descrição:

~/Desktop > file * | grep "image"

depois, cortei apenas o nome do arquivo de cada linha:

~/Desktop> file * | grep "image" | cut -d: -f1

A partir desta etapa, não sei como mover todos os nomes de arquivos obtidos para um diretório, tentei xargs, mas acho que entendi errado:

~/Desktop> file * | grep "image" | cut -d: -f1 | xargs mv {} ./dirk
    
por Abdul Al Hazred 12.03.2016 / 19:04

2 respostas

1

Veja a opção --target-directory para mv .

    
por 12.03.2016 / 19:09
0

{} não é significativo para xargs , a menos que você passe a opção -i com uso suspenso ou use -I {} .

file * | grep "image" | cut -d: -f1 | xargs -I {} mv {} ./dirk

Isso só funciona se os nomes dos arquivos não contiverem caracteres especiais ( :\"' ou newline ou um - ; espaços iniciais funcionam com xargs -I ). Isso também inclui nomes de arquivos que contêm images , mesmo que não sejam imagens. Isso inclui arquivos que o comando file descreve como “imagem”, como “imagem de disco”, não apenas imagens como nas imagens.

Uma maneira mais confiável (mas não perfeita) de filtrar arquivos cujo conteúdo é uma imagem é usar file -i e procurar por arquivos descritos como FILENAME: image/TYPE . O trecho abaixo também converte caracteres de citação que confundem algumas versões de xargs ¹.

file -i ./* |
sed -n -e 's/["'\''\]/\&/' -e 's/: *image\/[^:]*$//p' |
xargs -I {} mv {} ./dirk

Com versões razoavelmente recentes dos utilitários GNU (ou seja, sistema Linux não integrado ou Cygwin), você pode usar listas separadas por nulos para tornar o processamento confiável e um pouco mais rápido.

file -0i ./* |
sed -z -e 's/: *image\/[^:]*$//p' |
xargs -0 mv -t ./dirk

Outra abordagem, que tem o benefício de funcionar mesmo se file * falhar devido ao limite de comprimento da linha de comando, é usar um loop ou find para iterar os arquivos.

for x in ./*; do
  if [ -n "$(file -i "$x" | sed -n '$/: *image\/[^:]*$/ p')" ]; then
    mv "$x" ./dirk
  fi
done

¹ POSIX diz que -I desabilita o processamento de cotações de xargs , mas este não é o caso na versão GNU a partir do findutils 4.4.2.

    
por 14.03.2016 / 00:10