Como mover todos os arquivos do diretório atual para o diretório superior?

126

Como mover todos os arquivos do diretório atual para o diretório superior no linux?

Eu tentei algo como mv *.* , mas não funciona.

    
por Jens Erat 28.10.2009 / 19:54

11 respostas

194

O comando que você está procurando é

mv * .[^.]* ..

ou (veja abaixo para mais informações):

(shopt -s dotglob; mv -- * ..)

Explicação: o comando mv move arquivos e diretórios. O último argumento para mv é o destino (neste caso, o diretório um passo "para cima" na árvore, .. ). Os argumentos anteriores são os arquivos e diretórios de origem. O asterisco ( * ) é um caractere curinga que corresponde a todos os arquivos que não iniciam com um ponto. Arquivos que começam com um ponto (dotfiles) estão "ocultos". Eles são correspondidos usando o padrão .[^.]* (veja a edição abaixo).

Veja a página de manual que eu vinculei para mais informações sobre mv .

Por que .[^.]* em vez de .* ?

Como Chris Johnsen aponta corretamente: o padrão .* também corresponde a . e .. . Como você não quer (e não pode) movê-los, é melhor usar um padrão que corresponda a qualquer nome de arquivo começando com um ponto exceto aqueles dois . O padrão .[^.]* faz exatamente isso: ele combina qualquer nome de arquivo (1) começando com um ponto (2) seguido por um caractere que é não um ponto (3) seguido por zero ou mais caracteres arbitrários.

Como Paggas aponta , nós também teríamos que adicionar o padrão .??* para combinar arquivos começando com dois pontos. Veja a resposta dele para uma solução alternativa usando find .

Arjan's answer menciona shopt para evitar todos esses problemas com dotfiles. Mas ainda há o problema com os arquivos que começam com um traço. E isso requer três comandos. Ainda assim, gosto da ideia. Eu proponho usá-lo assim:

(shopt -s dotglob; mv -- * ..)

Isso executa shopt em uma subshell (portanto, não é necessária uma segunda chamada para shopt ) e usa -- para que os arquivos iniciados com um traço não sejam interpretados como argumentos para mv .

    
por 28.10.2009 / 20:01
42

Resposta curta: use

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

Resposta longa:

O comando

mv * .* ..

não funcionará, pois .* pode corresponder a . e .. . Mas o comando

mv * .[^.]* ..

também não funcionará, pois .[^.]* não corresponderá, por exemplo, ..filename ! Em vez disso, o que eu faço é

mv * .[^.] .??* ..

que corresponderá a tudo, exceto . e .. . * corresponderá a tudo que não começar com . , .[^.] corresponderá a todos os nomes de 2 caracteres começando com um ponto, exceto .. , e .??* corresponderá a todos os nomes de arquivos começando com um ponto com pelo menos 3 caracteres.

Melhor ainda, você pode usar

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

que evita os ataques feios da glob em mv * .[^.] .??* .. !

    
por 28.10.2009 / 21:19
14

Apenas por questão de integridade, também é possível dizer ao shell Bash para incluir arquivos ocultos, usando shopt :

shopt -s dotglob
mv -- * ..
shopt -u dotglob
    
por 28.10.2009 / 21:52
8

O mv não tem a funcionalidade de mover arquivos ocultos ao usar * - então porque não usar a cópia?

cp -rf . ..

rm -rf *

Não há necessidade de entrar em soluções complexas de "dotglobbing" e de usar comandos de localização.

    
por 02.08.2011 / 22:46
6
rsync -a --remove-source-files . ..

rsync é uma ferramenta de cópia de arquivos extremamente poderosa, geralmente usada para executar backups remotos incrementais eficientes e espelhos.

Com o comando acima, estamos dizendo a rsync para copiar o conteúdo de . para ..

O comutador -a ativa a recursão em subdiretórios . e ativa algumas outras opções comuns.

O comutador --remove-source-files diz ao rsync para remover os arquivos de origem após uma cópia bem-sucedida, isto é, faz o rsync se comportar de maneira semelhante ao comando mv .

    
por 20.01.2013 / 12:47
2

Por fim, o mv . falhará porque o mv não poderá desvincular o diretório em que você está. Você pode mv * .. mover os arquivos no cwd.

    
por 28.10.2009 / 19:59
2
mv * .??* ../.

* obtém todos os arquivos não pontuados. .??* recebe todos. arquivos com pelo menos três bytes de comprimento, o que funciona para todos os legítimos. Qualquer coisa que você tenha, provavelmente, deseja rm em vez de mv .

O ../. não oferece nenhum benefício direto sobre .. , mas ao fazer um movimento para o diretório é um hábito muito bom entrar, porque ele falhará, como você quiser, se houver algo errado com o caminho. Por exemplo, mv xyz bletch , onde você pensa que bletch é um diretório, pode ser mais certo com mv xyz bletch/. .

    
por 28.10.2009 / 20:47
2

Este comando minimizado funciona na maioria dos shells modernos:

\mv -- {,.{[^.],??}}* ..

Caso contrário, é uma solução portátil:

\mv -- * .[^.] .??* ..

Funcionalidades:

  1. \ impede que os aliases alterem mv de maneira indesejada.

  2. - impede que nomes de arquivos contendo hífens principais (-xyz) sejam interpretados como argumentos de linha de comando.

  3. . [^.] corresponde a todos os nomes de dois caracteres que começam com. exceto ..

  4. . * * corresponde a todos os outros nomes de arquivos com três ou mais caracteres.

Implementações ingênuas:

  1. O seguinte pula nomes de arquivos UNIX, aqueles que começam com. (.bashrc).

    mv * ..
    
  2. As seguintes correspondências .. que recursivamente tenta mover todos os diretórios eventualmente para / para .. do diretório de trabalho atual ($ PWD ou pwd). Nunca use.

    mv .* ..
    
por 12.08.2011 / 10:12
2

É mais correto usar o padrão * .[!.] .??* do que * .[^.] .??* , já que o primeiro também funciona com shells mais antigos, como o ksh88:

mv -- * .[!.] .??* ..
  • -- evita problemas quando você tem um nome de arquivo que começa com -
  • * corresponde a todos os nomes de arquivos que não começam com .
  • não há nomes de arquivo de caractere que começam com . , que você pode / deve mover
  • .[!.] corresponde a todos os nomes de arquivos de dois caracteres que começam com .
  • .??* corresponde a todos os nomes de três caracteres (ou mais) que começam com .

Com o ksh88, o padrão de nome de arquivo .[^.] corresponderá de fato aos nomes dos arquivos .. (que sempre existe) e .^ (que provavelmente não existem), tendo um efeito oposto ao desejado.

    
por 23.10.2013 / 00:24
0

Encontrar e grep também funcionam. Esse tipo de estrutura pode ser útil se você quiser selecionar arquivos em critérios mais complicados, modificando find e egrep.

find -maxdepth 1 | egrep '^./.'         # Returns all files

mv 'find -maxdepth 1 | egrep '^./.'' .. # mv <all files> ..
    
por 13.05.2014 / 01:08
0

Acho a solução mais fácil para mover todos os arquivos para o diretório pai. seria

mv "'ls'" ../

ou Se houver arquivos / diretórios ocultos

use:

mv "'ls -a'" ../ 2>/dev/null

Além disso, digamos que você queira mover o conteúdo de alguma pasta para uma de suas pastas internas tony (digamos)

use:

mv "'ls -a'" /tony 2>/dev/null

Nota:

"'ls -a'" 

Para mover os arquivos que possuem espaços.

2>/dev/null

É para suprimir o aviso / erro porque ls -a também imprimia a pasta . e .. e você não pode movê-los ou copiá-los. Então, para essas pastas, ele mostrará o erro (se não usarmos 2 > / dev / null), ele não poderá movê-las e o restante será movido com bastante conforto.

Melhor evitar ls -a se não houver arquivos ocultos e apenas usar ls .

    
por 06.08.2014 / 18:37

Tags