Como você move todos os arquivos (incluindo ocultos) de um diretório para outro?

114

Como faço para mover todos os arquivos em um diretório (incluindo os ocultos) para outro diretório?

Por exemplo, se eu tiver uma pasta "Foo" com os arquivos ".hidden" e "notHidden" dentro, como faço para mover os dois arquivos para um diretório chamado "Bar"? O seguinte não funciona, pois o arquivo ".hidden" permanece em "Foo".

mv Foo/* Bar/

Tente você mesmo.

mkdir Foo
mkdir Bar
touch Foo/.hidden
touch Foo/notHidden
mv Foo/* Bar/
    
por Cory Klein 24.01.2011 / 20:18

9 respostas

136

Zsh

mv Foo/*(DN) Bar/

ou

setopt -s glob_dots
mv Foo/*(N) Bar/

(Deixe de fora o (N) se você souber que o diretório não está vazio.)

Bash

shopt -s dotglob nullglob
mv Foo/* Bar/

Ksh93

Se você souber que o diretório não está vazio:

FIGNORE='.?(.)'
mv Foo/* Bar/

Padrão (POSIX) sh

for x in Foo/* Foo/.[!.]* Foo/..?*; do
  if [ -e "$x" ]; then mv -- "$x" Bar/; fi
done

Se você estiver disposto a permitir que o comando mv retorne um status de erro, mesmo que tenha sido bem-sucedido, é muito mais simples:

mv Foo/* Foo/.[!.]* Foo/..?* Bar/

GNU find e GNU mv

find Foo/ -mindepth 1 -maxdepth 1 -exec mv -t Bar/ -- {} +

Pesquisa padrão

Se você não se importa em mudar para o diretório de origem:

cd Foo/ &&
find . -name . -o -exec sh -c 'mv -- "$@" "$0"' ../Bar/ {} + -type d -prune

Veja mais detalhes sobre como controlar se os arquivos de ponto são correspondidos no bash, ksh93 e zsh.

Bash

Defina a dotglob opção .

$ echo *
none zero
$ shopt -s dotglob
$ echo *
..two .one none zero

Há também a GLOBIGNORE variable mais flexível, que você pode definir uma lista separada por dois pontos de padrões de caractere curinga para ignorar. Se não definido (a configuração padrão), o shell se comporta como se o valor estivesse vazio se dotglob estivesse definido e como se o valor fosse .* se a opção não fosse definida. Consulte Expansão do nome de arquivo no manual. Os diretórios difusos . e .. são sempre omitidos, a menos que . seja correspondido explicitamente pelo padrão.

$ GLOBIGNORE='n*'
$ echo *
..two .one zero
$ echo .*
..two .one
$ unset GLOBIGNORE
$ echo .*
. .. ..two .one
$ GLOBIGNORE=.:..
$ echo .*
..two .one

Ksh93

Defina a FIGNORE variable . Se não definido (a configuração padrão), o shell se comportará como se o valor fosse .* . Para ignorar . e .. , eles devem ser correspondidos explicitamente (o manual em ksh 93s + 2008-01-31 declara que . e .. são sempre ignorados, mas isso não descreve corretamente o comportamento real).

$ echo *
none zero
$ FIGNORE='@(.|..)'
$ echo *
..two .one none zero
$ FIGNORE='n*'
$ echo *
. .. ..two .one zero

Você pode incluir arquivos de ponto em um padrão combinando-os explicitamente.

$ unset FIGNORE
$ echo @(*|.[^.]*|..?*)
..two .one none zero

Para que a expansão saia vazia se o diretório estiver vazio, use a opção de correspondência de padrão N : ~(N)@(*|.[^.]*|..?*) ou ~(N:*|.[^.]*|..?*) .

Zsh

Defina a dot_glob opção .

% echo *
none zero
% setopt dot_glob
% echo *
..two .one none zero

. e .. nunca são correspondidos, mesmo que o padrão corresponda explicitamente à . .

% echo .*
..two .one

Você pode incluir arquivos de pontos em um padrão específico com o D qualificador de glob .

% echo *(D)
..two .one none zero

Adicione o qualificador N glob para tornar a expansão vazia em um diretório vazio: *(DN) .

Observação: você pode obter resultados de expansão de nome de arquivo em pedidos diferentes (por exemplo, none seguido por .one seguido por ..two ) com base nas suas configurações das variáveis LC_COLLATE , LC_ALL e LANG .

    
por 24.01.2011 / 21:25
24
#!/bin/bash

shopt -s dotglob
mv Foo/* Bar/

De man bash

dotglob If set, bash includes filenames beginning with a '.' in the results of pathname expansion.

    
por 24.01.2011 / 20:38
5

Uma maneira simples de fazer isso em bash é

mv {Foo/*,Foo/.*} Bar/

Mas isso também moverá diretórios.

Se você quiser mover todos os arquivos, incluindo oculto, mas não quiser mover nenhum diretório, use um loop e teste.

for i in $(ls -d {Foo/*,Foo/.*});do test -f $i && mv -v $i Bar/; done;

    
por 11.08.2013 / 21:34
4

Uma maneira é usar find :

find Foo/ -type f -exec mv -t Bar/ {} \+

O -type f restringe o comando find para localizar arquivos. Você deve investigar as opções -type , -maxdepth e -mindepth de find para personalizar seu comando para considerar os subdiretórios. O Find tem uma página de manual muito extensa, mas muito útil, .

    
por 24.01.2011 / 20:46
2

Experimente o comando de cópia cp :

$ cp -r myfolder/* destinationfolder

cp -r significa cópia recursiva, portanto todas as pastas e arquivos serão copiados.

Você pode usar o comando de remoção rm para remover uma pasta:

$ rm -r myfolder

Veja mais: mova tudo arquivos de um diretório para outro .

    
por 11.05.2014 / 04:52
1

O rsync é outra opção:

rsync -axvP --remove-source-files sourcedirectory/ targetdirectory

Isso funciona porque, no rsync, a barra à direita é importante, sourcedirectory/ refere-se ao conteúdo do diretório, enquanto sourcedirectory se referiria ao próprio diretório.

A desvantagem deste método é que o rsync somente limpará os arquivos após a movimentação, não o diretório. Então você fica com uma árvore vazia de sourcedirectory. Para obter soluções alternativas para isso, consulte:

Mover arquivos e excluir diretórios com o rsync?

Portanto, embora isso possa não ser ideal para operações de movimentação, pode ser extremamente útil para operações de cópia.

    
por 07.07.2018 / 19:16
1

Resposta para bash / fish

Aqui está uma maneira de fazer isso usando curingas:

.[!.]* ..?* corresponderá a todos os arquivos ocultos , exceto . e ..

.[!.]* ..?* * corresponderá a todos os arquivos (ocultos ou não) , exceto . e ..

E para responder ao exemplo específico desta questão, você precisa de cd foo && mv .[!.]* ..?* * ../bar

Explicação

.[!.]* corresponde a nomes de arquivos que começam com um ponto, seguido por qualquer caractere, exceto o ponto opcionalmente seguido por qualquer string. Isso está perto o suficiente, mas falta arquivos começando com dois pontos como ..foo . Para incluir esses arquivos, adicionamos ..?* que corresponde aos nomes dos arquivos que começam com dois pontos, seguidos por qualquer caractere, opcionalmente seguido por qualquer string.

Teste

Você pode testar esses curingas com os comandos abaixo. Eu tentei com sucesso sob bash e peixe. Eles falham sob sh, zsh, xonsh.

mkdir temp
cd temp
touch  a  .b  .bc  ..c  ..cd  ...d  ...de
ls .[!.]* ..?*
# you get this output:
          .b  .bc  ..c  ..cd  ...d  ...de
# cleanup
cd ..
rm -rf temp
    
por 06.11.2017 / 16:44
0

Você também pode encontrar e localizar com backquotes para selecionar arquivos para o comando move. Passe isso para o mv.

Ou seja. Para arquivos ocultos

find Foo -maxdepth 1 | egrep '^Foo/[.]' # Output: .hidden

Então

mv 'find Foo -maxdepth 1 | egrep '^Foo/[.]'' Bar # mv Foo/.hidden Bar

Move apenas os arquivos ocultos selecionados para Bar :

mv 'find Foo -maxdepth 1 | egrep '^Foo/.'' Bar # mv Foo/.hidden Foo/notHidden Bar

Move todos os arquivos em Foo para Bar desde o '.' no comando egrep age como um curinga sem os colchetes.

O caractere ^ garante que a correspondência comece no início da linha.

Alguns detalhes da correspondência de padrões egrep podem ser encontrados aqui .

O uso de maxdepth 1 impede que os locais entrem em subdiretórios.

    
por 13.05.2014 / 00:30
0

Inspirado em esta resposta :

Sem copiar os arquivos ...

rsync -ax --link-dest=../Foo/ Foo/ Bar

Advertências:

  • --link-dest path deve ser absoluto ou relativo a DESTINATION ( Bar no exemplo)

  • Você deve colocar / após SOURCE ( Foo/ no exemplo), caso contrário, copiará a pasta SOURCE em vez de seu conteúdo.

por 23.12.2015 / 09:40