Como você pode mover (ou copiar) todos os arquivos para um diretório com o mesmo prefixo de nome de arquivo?


9

Usando o Bash

Então, digamos que eu tenha um monte de arquivos colocados aleatoriamente em um diretório pai ~/src, quero pegar todos os arquivos correspondentes a um determinado sufixo e movê-los (ou copiá-los) para um ~/distdiretório.

Vamos supor para esse fim que todos os nomes de arquivos tenham esta convenção de nomenclatura:

<filename_prefix>.<filename_suffix>

Eu descobri que essa era uma maneira rápida de obter todos os arquivos com um determinado arquivo filename_suffixe colocá-los em uma pasta dist:

mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;

Agora, um passo adiante ... como posso usar a saída de find, nesse caso filename, e usar o filename_prefixpara gerar um diretório com o mesmo nome ~/diste depois mover (ou copiar) todos os arquivos com esse prefixo para o diretório apropriado?

mkdir ~/dst
find source -name "*.xrt,*.ini,*.moo" -exec mv -i {} -t ~/dst \;

Essencialmente, como altero o comando acima (ou talvez use outro comando), para criar uma estrutura como esta

(RESULTADO)

~/dist/people/people.xrt
~/dist/games/games.xrt
~/dist/games/games.moo
~/dist/games/games.ini
~/dist/monkeys/monkeys.ini
~/dist/monkeys/monkeys.xrt

de uma árvore de diretórios como esta?

(ENTRADA)

~/src/xrt/people.xrt
~/src/xrt/games.xrt
~/src/conf/games.ini
~/src/pack/monkeys.xrt
~/src/e344/games.moo
~/src/e344/monkeys.moo
~/src/en-us/monkeys.ini

Respostas:


10

Seria um inferno dizer findo que fazer neste caso.

Melhor usar o shell:

for i in **/*.{xrt,ini,moo}; do
  FILE=$(basename "$i")
  DIR=~/dst/${FILE%.*}
  echo mkdir -p -- "$DIR"
  echo mv -i -t "$DIR" -- "$i"
done

Use shopt -s globstarpara fazer a **glob funcionar (ou use zsh!). E remova echos mais tarde se o comando imprimir o que você deseja.


usando bash é o mesmo?
— Qodeninja 6/02/12

@ codeninja shopt -s globstar, veja minha edição. Se houver apenas dois níveis, você poderá usar */*.*e o snippet funcionará em qualquer shell.
— Gilles 'SO- stop be evil'

2

trapaça encontrar linha de comando:

find source -name "*.xrt,*.ini,*.moo" -exec env file={} bash -c 'base="$(basename "$file")";dir="dst/${base%.*}";mkdir -p "$dir";cp "$file" "$dir"' \;

na verdade, uma solução alternativa para chamar o script bash no find LOL.

= P


11
Adivinhe o que acontece se houver um arquivo chamado… happy rm -rf /! Esse tipo de código merece um -1.
— Stéphane Gimenez

A sua edição não é suficiente: digamos que você cliked em um link e baixado Yay" rm -rf / "Rox0r.avi, novamente não é como um problema ...
— Stéphane Gimenez

(E não há como tornar esse tipo de substituição seguro).
— Stéphane Gimenez

11
Ah, talvez seja possível fazer isso de maneira diferente. Parece que as seguintes obras: -exec bash -c 'command which uses "$1"' bash '{}' ';'. Bem, é inútil de qualquer maneira.
— Stéphane Gimenez

11
@ StéphaneGimenez feito, bash não é a única coisa a usar. LOL
— yuyichao 7/02
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.