Como mover recursivamente todos os arquivos (incluindo ocultos) em uma subpasta para uma pasta pai no * nix?

14

Essa é uma pergunta um pouco embaraçosa, mas devo admitir que, no final da minha carreira, ainda tenho dúvidas sobre o comando mv.

Frequentemente, tenho esse problema: preciso mover todos os arquivos recursivamente para um nível acima. Digamos que eu tenha a pasta foo e uma barra de pastas dentro dela. Bar tem uma bagunça de arquivos e pastas, incluindo arquivos e pastas de pontos. Como movo tudo na barra para o nível foo?

Se foo estiver vazio, simplesmente movo a barra um nível acima, excluo foo e renomeio a barra para foo. Parte do problema é que não consigo descobrir qual é o curinga do mv para "tudo, incluindo pontos". Uma parte dessa pergunta é esta - existe uma discussão aprofundada sobre os curingas que os comandos cp e mv usam em algum lugar (pesquisar no Google isso apenas traz tutoriais muito básicos).

programador morto
fonte

Respostas:

19

No Bash (e alguns outros), você pode usar a expansão de chaves para fazer isso em uma linha:

mv bar/{,.}* .

A vírgula separa um nulo e um ponto; portanto, o mvcomando vê nomes de arquivos que correspondem *e.*

Pausado até novo aviso.
fonte
isso também tenta mover '..', falha com a mensagem 'o recurso está ocupado'. Funciona, no entanto.
Xananax 02/04
3
Sugerida por usuário anônimo:To eliminate the error caused by also matching "." and "..", use this command: mv bar/{,.[!.],..?}* .
HopelessN00b
2

A maneira mais fácil de fazer isso é fazê-lo em dois comandos, porque * não corresponde a.

cd /foo
mv bar/* ./
mv bar/.??* ./

Você não deseja usar a barra /.* que descobri ao cometer este erro:

rm -rf ./.* 

Isso é uma coisa ruim. Alguém quer adivinhar por quê? ;-)

Matt Simmons
fonte
Eu não acho que Bash ou Zsh se expande .*para .e ... Zsh não faz para mim, pelo menos.
Mikael S
Mikael: Eu posso prometer que o bash faz (ou pelo menos fez), como eu tive de recuperar diretórios de usuário que eu dizimado por fazer exatamente isso
Matt Simmons
2

A primeira coisa a saber sobre globbing - é feito pelo shell, não pelo comando. Verifique a página de manual do seu shell para todos os detalhes.

Jeff Leyser
fonte
2

Este coleta todos os arquivos das subpastas e os move para o diretório atual

find . -type f -exec mv -iv \{} . \;

Se você deseja escrever arquivos com o mesmo nome, use

yes y | find . -type f -exec mv -iv \{} . \;
michelek
fonte
1

mv .??* *cuidará de qualquer coisa, exceto ponto seguido por um único caractere. Se isso for comum à sua situação, você pode adicionar .[a-zA-Z0-9]*. Isso ainda vai deixar os arquivos com nomes como .;, .^e .^I(TAB). Se você precisar lidar com tudo, precisará ser um pouco mais complexo.

mv .. `ls -f | egrep -v '^.$|^..$'
mpez0
fonte
0

Se você possui uma estrutura de diretórios /foo/bar/e deseja mover todos os arquivos em baruma etapa acima, entre no bardiretório e digite o seguinte:

find . -depth -print0 | cpio --null -pvd ../

Geralmente, acho que cpio(1)é melhor para esse tipo de tarefa. Você pode conferir a documentação detalhada emitindo info cpioem seu shell.

fim
fonte