Snippet Bash para mover todos os arquivos em um diretório para esse diretório

14

Eu tenho um diretório com muitos arquivos e diretórios nele. Para arrumar tudo, vou colocar todos esses arquivos em um diretório, então faria algo assim:

$ ls | wc -l
123
$ mkdir new_directory
$ mv * ./new_directory

No entanto, que, obviamente, não vai funcionar, porque então ele vai tentar se mover new_directoryem new_directory. Existe alguma maneira simples de fazer o que eu quero em uma linha sem que eu precise copiar e colar todos os arquivos e diretórios nesse diretório?

Rory
fonte
3
funciona, apenas imprime uma mensagem de erro informando que não é possível mover o new_directory para si próprio.
cas

Respostas:

18

Seu

mv * ./new_directory
comando realmente funcionará; apenas imprimirá um aviso de que não pode mover esse diretório para si próprio.

microônibus
fonte
O 'único' problema com isso é que, se a expansão total do comando se tornar muito longa (ou seja, muitos arquivos, nomes muito longos), isso não funcionará mais.
Niels Basjes
Como uma observação lateral, se você quiser fazer isso com a, git mvdeverá usar a -kflag, já que o git falhará por padrão, e não apenas cite um aviso. Então você precisará fazer git mv -k * ./new_dir.
Yuval A
11

Um oneliner rápido e sujo.

mv `ls -A | grep -v new_directory` ./new_directory

fonte
1
Não funcionará: um sl simples não mostrará arquivos de ponto.
wzzrd 8/09/09
Muito bom ponto. Corrigido isso com um -a.
2
Então, ao invés de tentar mudar o new_directory para si mesmo (pergunta original), agora você está tentando mudar. e .. em new_directory.
Niels Basjes
2
Obrigado pelo feedback Niels. Corrigido com um a superior que remove o. e o .. na lista de diretórios.
8

Se você está apenas procurando os arquivos (ou seja, não os diretórios), então

find . -type f -maxdepth 1 -exec mv {} ./new_directory/ \;

é a solução mais portátil. Para velocidade, você deve mover find e xargs, com -print0 e -0, mas somente se você tiver o GNU find e xargs.

Cian
fonte
3
Usando uma descoberta bastante recente do GNU, você também pode usar \ + em vez de \; para diminuir o número de mv que estamos produzindo.
wzzrd 8/09/09
Se você tem o GNU find, também pode usar o xargs, que fará o mesmo e permitir que você execute vários mvs ao mesmo tempo com o sinalizador -p.
Cian
arrefecer uso de find- embora eu tenha sido definitivamente em sistemas que não têm um, infelizmente :(
Warren
Verdade? find é (afaik) especificado no SUS, então tudo deve ter. O único problema é se é a localização do GNU (que tem muitas opções interessantes) ou a localização regular.
Cian
6

Nas vezes em que tive esse problema, fiz um dos seguintes:

$ mkdir ../new-directory
$ mv * ../new-directory/
$ mv ../new-directory .

ou

$ mkdir .new-directory
$ mv * .new-directory/
$ mv .new-directory new-directory

A segunda forma aproveita os nomes de arquivo de caractere curinga que começam com '.'

Kenster
fonte
Esqueci os arquivos pontilhados ignorados pelo curinga; Obrigado pela lembrança ! :)
aemonge
2

A respeito:

cd ..
mv old_dir new_directory
mkdir old_dir
mv new_directory old_dir

IOW, não mova o conteúdo para um novo diretório, mas coloque esse diretório dentro de um novo.

Javier
fonte
1

De maneira semelhante à resposta de @ Rembrane (embora não seja uma linha):

for FN in *
do
    if [ "<new_dir>" != $FN ] then
        mv $FN <new_dir>
done

Isso deve ser 100% portátil - mesmo se findestiver ausente do seu sistema.

Warren
fonte
find é necessário na única especificação unix. Como tal, ele nunca deve estar ausente (não que você não poderia construir algo com ele para fora Mas eu imagino que iria exigir uma quantidade terrível de esforço, e nenhum sistema fornecedor faltará-lo.)
Cian
talvez seja algum sysadmin hiper-paranóico que encontra yutins ou seu equivalente? Não tenho certeza, mas eu sei que eu tenho que correr para boxen que não tê-lo :(
Warren
1

Minhas sugestões: Como declarado por outros,

mv * ./new_directory

vai funcionar encontrar IFF a expansão total é curta o suficiente.

Caso contrário, você pode tentar este que pode ser escalado para um número muito maior de arquivos:

find . -type f -maxdepth 1 | xargs -s100000 echo | xargs -iXXX mv XXX new_directory

Explicação

  1. Listar todos os arquivos.
  2. Agrupe todos os nomes de arquivos em pedaços de no máximo 100000 caracteres.
  3. Construa um único comando mv por bloco.
Niels Basjes
fonte
breaks, se você tem quaisquer espaços em seus nomes de arquivos
Cian
Você está certo. Então eu acho que isso deve ser aumentado com sinalizadores -print0 e -0 para corrigir.
Niels Basjes
Eu tentei com -print0e -0e quebra ainda.
Cristian Ciupitu 08/09/09
find: warning: você especificou a opção -maxdepth após um argumento que não é da opção -type, mas as opções não são posicionais (-maxdepth afeta os testes especificados antes e os especificados depois). Especifique as opções antes de outros argumentos.
Cristian Ciupitu 08/09/09
1

Usar:

find -mindepth 1 -maxdepth 1 \! -name new_directory -print0 | \
    xargs -0 -P 100 -I'{}' mv '{}' new_directory

De xargs página manual:

-P max-procs

  Run up to max-procs processes at a time;
Cristian Ciupitu
fonte
-1

Para evitar a mensagem de erro e simplificar:

mv *.* ./new_Folder

fará a mesma coisa, mas evitará a mensagem de erro (a menos que você tenha pontos nos nomes das pastas, eu acho).

user157734
fonte