Como mover arquivos baseados na primeira palavra no nome do arquivo?

1

Em uma pasta, tenho milhares de arquivos, como:

cat eats mouse.jpg
cat chases mouse.jpg
gorilla eats banana.jpg
gorilla is sleeping.jpg
elephant is huge.jpg
elephant has trunk.jpg
(and so on...)

Eu quero um script bash que mova esses arquivos com base na primeira palavra do nome do arquivo (cat, gorilla, elephant, etc) em pastas, também criada com base na primeira palavra, para que:

    A pasta
  • 'cat' é criada e todos os arquivos que começam com 'cat' são movidos para essa pasta.
  • A pasta
  • 'gorilla' é criada e todos os arquivos que começam com 'gorilla' são movidos para essa pasta.
  • A pasta 'elephant' é criada e todos os arquivos que começam com elephant são movidos para essa pasta.
  • (e assim por diante ..)
por user163125 17.10.2014 / 18:09

2 respostas

7

O seguinte oneliner deve fazer o trabalho:

find . -maxdepth 1 -type f -name '*.jpg' -exec perl -e '$a="{}"; $a =~ /(\w+)/; 'mkdir -p  && mv "$a" '' \;

Explicação

  • find . -maxdepth 1 -type f -name '*.jpg' procurará arquivos ( -type f ) somente na pasta atual ( . -maxdepth 1 ) com a extensão jpg.

  • -exec chamará o comando perl para todos os arquivos correspondentes. A string {} é substituída pelo nome do arquivo atual que está sendo processado.

  • $a="{}"; salva o arquivo atual

  • $a =~ /(\w+)/ é um teste de expressão regular, a variável especial conterá a primeira palavra do nome do arquivo armazenado em $a .

  • finalmente mkdir -p && mv "$a" é executado como um comando do sistema com /bin/sh ou seu equivalente. Observe a opção -p de mkdir , não falhará se o diretório já existir.

Atualizar

Para evitar a injeção de código no perl (obrigado @ geirha ), use o quotemeta funcionam da seguinte forma:

find . -maxdepth 1 -type f -name '*.jpg' -exec perl -e '$a="\Q@ARGV"; $a =~ /(\w+)/; 'mkdir -p  && mv $a '' "{}" \;
    
por Sylvain Pineau 17.10.2014 / 18:22
3

Eu usaria um loop for para isso.

for file in ./*" "*.jpg; do
    word=${file%% *}
    mkdir -p "$word" &&
    mv "$file" "$word"
done

Você pode executar isso em um shell interativo ou colocá-lo em um script. Bash é muito útil para saber, então eu recomendo aprender lendo o Guia de Bash quando você tiver tempo.

    
por geirha 19.10.2014 / 12:41