Estrutura de diretório de achatamento

14

Eu tenho um monte de pastas dentro de pastas. Como isso

Root Folder
    -- Folder 1
    -- Folder 2
    -- Folder 3
    -- Folder 4

Eu quero recolher todas as pastas para que todos os arquivos na pasta1, pasta 2, pasta 3, ... pasta n existe na pasta raiz.

Qual é a maneira mais rápida de fazer isso no Windows?

Mais de cinco
fonte
5
Depende, como você deseja lidar com nomes de arquivos duplicados?
Mark Allen

Respostas:

16

Não há motivos para usar ferramentas especiais ou mesmo scripts. Basta usar a função de pesquisa no Explorer.

  1. Abra a pasta que você deseja nivelar no Explorer.
  2. Crie uma nova pasta, selecione todos os arquivos (mas não as pastas) e arraste-os para essa pasta (isso evitará a obtenção de duas cópias desses arquivos).
  3. Na caixa de pesquisa (aquela à direita da barra de endereços), digite *e pressione Enter.
  4. Depois que a lista for preenchida, clique com o botão direito do mouse e selecione todos, clique com o botão direito e corte.
  5. Pressione o botão de retorno para voltar para a pasta original, clique com o botão direito e cole.
  6. Se você tiver nomes duplicados, será perguntado sobre como lidar com isso. Escolha a opção mais apropriada para o seu caso de uso. (Suponho que seria para copiar os dois arquivos.) Para evitar ser solicitado novamente, não se esqueça de aplicar isso a todos os arquivos com a caixa de seleção na parte inferior.
  7. Selecione todas as pastas, verifique se estão vazias, observando o pop-up sobre o número de arquivos selecionados e exclua-os.

Se você preferir ter um script para iniciá-lo e esquecê-lo, isso também pode ser feito. O comando para substituir mv *\* .é bem fácil ( for /r %f in (*.*) do @move "%~f" .), mas tenho certeza que você gostaria de lidar com duplicatas, sem deixá-las para trás, como na resposta do @Nicole Hamilton. Acrescentar um número ao nome de arquivo das duplicatas é provavelmente a maneira mais fácil de fazê-lo.

Copie e cole o seguinte arquivo em lotes no Bloco de Notas e salve-o como "flatten.cmd" (incluindo as aspas):

@echo off
cd "%~1"
md tempryfolder
move *.* tempryfolder
for /r %%f in ("*.*") do call :START "%%~f"
for /r /d %%f in (*.*) do rd "%%~f" 
GOTO :EOF
:START
setlocal
If exist "%~n1%~x1" set /a num=2
:LOOP
If exist "%~n1%num%%~x1" (
    set /a num+=1
    goto loop
)
move "%~1" "%~n1%num%%~x1"

Para usar o script, basta arrastar a pasta que você deseja nivelar sobre ela.

trlkly
fonte
Semelhante, mas mais fácil de entender: superuser.com/a/523854/433830
aparente001
Nota: este script é essencialmente uma bomba bifurcada. Eu estou usando em uma pasta com milhares de subdiretórios e dezenas de milhares de subarquivos e a pegada de memória está aumentando lentamente. Eu não acho que vou me deparar com problemas de OOM, mas é algo para se ter em mente.
Nzall
@Nzall Não tenho nenhum problema em acreditar que poderia fazer isso, mas culparia a Microsoft, não meu código. Tudo o que faço é chamar uma sub-rotina no arquivo de lote várias vezes. E nunca executo mais de uma vez: cada sub-rotina é executada até a conclusão, executando apenas um processo por vez. Quanta memória estamos falando sobre o uso?
trlkly
@trlkly Em certo ponto, ele subiu para 2 GB, embora eu tenha uma grande quantidade de pastas e subpastas, cerca de 75.000 arquivos e milhares de pastas. Alguns momentos depois caiu para cerca de 8-900 MB. Havia um monte de arquivos duplicados embora. Eu estava achatando 12 cópias de uma biblioteca de 7.500 arquivos para que eu pudesse testar como certos softwares lidariam com uma pasta com dezenas de milhares de arquivos.
Nzall
@Nzall Isso é incrivelmente estranho para mim. Nada do roteiro deve fazer isso. É uma sub-rotina que reutiliza uma única variável para incrementar o arquivo. Posso ter que perguntar o que poderia causar esse uso de memória tão grande em SO ou algo assim.
trlkly
4

Você pode achatar no Windows Explorer, navegando até a pasta que deseja nivelar e procurando para System.Kind:<>folderexcluir pastas dos resultados.

Você pode selecionar todos os arquivos com CTRL + A e copiá-los e colá-los em uma nova pasta. Observe que o Windows Explorer perguntará a você como lidar com nomes de arquivos duplicados.

insira a descrição da imagem aqui

Mateus
fonte
1
note que para isso funcionar você precisa digitar "pasta" na tradução localizada correspondente (por exemplo, em italiano é System.Kind:<>cartella)
JohnKiller
0

Esse tipo de coisa é fácil com um shell Unix. Aqui está o que você poderia fazer com meu próprio shell Hamilton C (incluindo a versão gratuita ). Você poderia fazer algo muito semelhante com o Cygwin bash.

mv *\* .

Se o seu diretório é realmente grande, é possível que o curinga tenha ocorrido em uma linha de comando muito longa para o Windows passar para um processo filho. (A chamada do Windows CreateProcess limita a lista de argumentos a 32K caracteres Unicode.) Mas o shell C não tem limite internamente, portanto, você poderia iterar pela lista inteira dessa maneira:

foreach i ( *\* )
   mv $i .
end

Para o ponto de @ MarkAllen acima, este tipo de pressupõe que não há nomes duplicados. Se houver, as cópias posteriores na lista substituirão as mais antigas. Se isso é uma preocupação, você pode iterar sobre os arquivos, mvusando-os somente se não estiver sobrescrevendo. O :toperador é o operador de cauda . O -eoperador é o arquivo existe teste .

foreach i ( *\* )
   if ( -e $i:t ) then
      echo -2 $i not moved because it already exists
   else
      mv $i .
   end
end

Isso ainda deixa os diretórios vazios, o que talvez você não queira depois que eles forem esvaziados. Essa poderia ser a próxima iteração se isso importasse.

Nicole Hamilton
fonte
Usando cygwin> mv *. mv: não pode stat `* ': Não existe arquivo ou diretório
Mais do que 5 de
No Cygwin bash, mv */* .funciona para mim.
Nicole Hamilton
3
Algumas pessoas são tão fixas no UNIXismo ... Se você realmente quer fazer scripts no Windows 7, há o PowerShell, você não precisa de algum falso simulador de bash como o Cygwin.
Você nem precisa do PowerShell. A linha de comando regular ainda existe e pode fazer as mesmas coisas. Veja minha resposta abaixo.
trlkly