Como mover todos os ficheiros do directório actual para o directório superior?
Como mover todos os ficheiros do directório actual para o directório superior no linux?
Eu tentei algo como mv *.*
, mas não funciona.
Como mover todos os ficheiros do directório actual para o directório superior no linux?
Eu tentei algo como mv *.*
, mas não funciona.
O comando que procura é
mv * .[^.]* ..
``` ```
(shopt -s dotglob; mv -- * ..)
ou (ver abaixo para mais informações):
(shopt -s dotglob; mv -- * ..)
Explicação: o comando mv
move ficheiros e directórios. O último argumento para mv
é o alvo (neste caso o directório um passo “para cima” na árvore, ..
). Os argumentos antes disso são os ficheiros e directórios de origem. O asterisco (*
) é um asterisco que corresponde a todos os ficheiros que não começam com um ponto. Os ficheiros que começam com um ponto (dotfiles) são “escondidos”. São combinados utilizando o padrão .[^.]*
(ver edição abaixo).
Veja a página de manual que liguei para mais informações sobre mv
.
.[^.]*
em vez de .*
?Como Chris Johnsen aponta correctamente: o padrão .*
também corresponde a .
e ..
. Uma vez que não quer (e não pode) movê-los, é melhor utilizar um padrão que corresponda a qualquer nome de ficheiro começando com um ponto exceto esses dois. O padrão .[^.]*
faz exactamente isso: corresponde a qualquer nome de ficheiro (1) começando com um ponto (2) seguido de um caractere que é não um ponto (3) seguido de zero ou mais caracteres arbitrários.
Como Paggas pontos , também teríamos de adicionar o padrão .??*
a fim de combinar ficheiros que comecem com dois pontos. Ver a sua resposta para uma solução alternativa usando find
.
A resposta de Arjan menciona shopt
a fim de evitar todos aqueles problemas com ficheiros de pontos. Mas depois há ainda o problema com ficheiros que começam com um traço. E requer três comandos. Ainda assim, gosto da ideia. Proponho usá-la desta forma:
0x1&
Isto executa shopt
numa subcapa (portanto não é necessária uma segunda chamada para shopt
) e utiliza --
para que os ficheiros que começam com um traço não sejam interpretados como argumentos para mv
.
Resposta curta: usar
find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +
Resposta longa:
O comando
mv * .* ..
não funcionará uma vez que .*
pode corresponder a .
e ..
. Mas o comando
mv * .[^.]* ..
também não funcionará, uma vez que .[^.]*
não combinará, por exemplo, ..filename
! Em vez disso, o que eu faço é
mv * .[^.] .??* ..
que combinará com tudo excepto .
e ..
. *
corresponderá a tudo o que não comece com um .
, .[^.]
corresponderá a todos os nomes de ficheiros de 2 caracteres começando com um ponto excepto ..
, e .??*
corresponderá a todos os nomes de ficheiros começando com um ponto com pelo menos 3 caracteres.
Melhor ainda, poderá usar
find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +
o que evita os feios hacks do globo em mv * .[^.] .??* ..
!
O mv não tem a funcionalidade de mover ficheiros escondidos quando usa *
- então porque não usar cópia em vez disso?
cp -rf . ..
rm -rf *
Não é necessário entrar em soluções complexas de dotglobbing e utilizar comandos de procura.
rsync -a --remove-source-files . ..
rsync
é uma ferramenta de cópia de ficheiros extremamente poderosa, geralmente utilizada para efectuar backups e espelhos remotos incrementais eficientes.
Com o comando acima, estamos a dizer a rsync
para copiar o conteúdo de .
para ..
A opção -a
permite a repetição em .
subdirectórios e permite algumas outras opções comuns.
A comutação --remove-source-files
diz ao rsync para remover os ficheiros fonte após uma cópia bem sucedida, ou seja, faz com que o rsync se comporte de forma semelhante ao comando mv
.
Este comando minimizado funciona na maioria das conchas modernas:
\mv -- {,.{[^.],??}}* ..
Caso contrário, é uma solução portátil:
\mv -- * .[^.] .??* ..
Faatures:
\ Impede que os pseudónimos alterem a mv de forma indesejável.
– impede que nomes de ficheiros contendo hífenes principais (-xyz) sejam interpretados como argumentos de linha de comando.
.[^.] corresponde a todos os nomes de ficheiros de dois caracteres começando por … excepto …
.??^* corresponde a todos os outros nomes de ficheiros de três caracteres ou mais.
Aplicações ingénuas:
Os seguintes salta nomes de ficheiros UNIX escondidos, aqueles que começam com . (.bashrc).
Os seguintes correspondem … que repetidamente tentam mover todos os directórios eventualmente de volta para / para … do directório de trabalho actual ($PWD ou pwd). Nunca usar.
Em última análise, tentar mv .
falhará porque mv não será capaz de desvincular o directório em que se encontra actualmente. Poderá mv * ..
para mover os ficheiros no cwd.
É mais correcto utilizar o padrão * .[!.] .??*
do que * .[^.] .??*
uma vez que o primeiro também funcionará com conchas mais antigas como a ksh88:
mv -- * .[!.] .??* ..
--
previne problemas quando se tem um nome de ficheiro que começa com -
*
corresponde a todos os nomes de ficheiro que não começam com um .
.
que pode/deve mover .[!.]
corresponde aos nomes dos ficheiros de dois caracteres que começam com um .
.??*
corresponde aos nomes dos ficheiros de três caracteres (ou mais longos) que começam com um .
Com ksh88, o padrão do nome do ficheiro .[^.]
irá de facto corresponder aos nomes do ficheiro ..
(que sempre existe) e .^
(que provavelmente não existe), tendo um efeito oposto ao desejado.
mv * .??* ../.
*
recebe todos os ficheiros não pontos. .??*
recebe todos os ficheiros . com pelo menos três bytes de comprimento, o que funciona para todos os legítimos. Tudo o que lhe sobrar provavelmente quer rm
em vez de mv
de qualquer forma.
O ../.
não oferece quaisquer benefícios directos sobre ..
mas ao fazer uma mudança para directório é um hábito muito bom de se entrar, porque falhará, como quiser, se houver algo de errado com o caminho. Por exemplo, mv xyz bletch
, onde você pense bletch
é um directório, pode ser mais seguro com mv xyz bletch/.
.
Encontrar e trabalhar também o grep work. Este tipo de estrutura pode ser útil se quiser seleccionar ficheiros com critérios mais complicados, modificando o find e o grep.
find -maxdepth 1 | egrep '^./.' # Returns all files
mv `find -maxdepth 1 | egrep '^./.'` .. # mv <all files> ..
Acho que a solução mais fácil para mover todos os ficheiros para a sua sede seria
mv "`ls`" ../
ou, se houver ficheiros/directórios ocultos
utilizar:
mv "`ls -a`" ../ 2>/dev/null
Além disso, digamos que se pretende mover o conteúdo de alguma pasta para uma das suas pastas internas tony(digamos)
utilização:
mv "`ls -a`" /tony 2>/dev/null
Nota:
"`ls -a`"
Para mover os ficheiros que têm espaços.
2>/dev/null
É para suprimir o aviso/erro porque ls -a
imprimiria também a pasta .
e ..
e não se pode movê-los ou copiá-los. Assim, para essas pastas mostrará erro (se não usarmos 2>/dev/null) que não as pode mover e o resto será movido bastante confortavelmente.
Melhor evitar ls -a
se não houver ficheiros escondidos e usar apenas ls
.