Comando de toque recursivo do Windows

17

No Windows 7, como posso tocar recursivamente todos os arquivos em um diretório (incluindo subdiretórios) para atualizar o carimbo de data / hora?

O Windows 7 tem um mecanismo para fazer isso?

jmq
fonte
possível duplicata do Windows equivalente ao comando Linux 'touch'?
Pausado até novo aviso.
A resposta "aceita" nesse link é sobre o uso de bibliotecas de programação .NET para realizar isso em um arquivo. Os outros foram sobre a adição de um menu de contexto para atualizar arquivos únicos. Eu estava procurando por um comando interno para fazê-lo em N arquivos recursivamente. A resposta abaixo trabalhou para todos os arquivos. Não é um built-in, mas funciona. Obrigado.
JMQ
Também não é uma duplicata da versão para Windows do comando touch do Unix , porque esta pergunta está solicitando especificamente recursão. No entanto, observe que algumas respostas a essa pergunta têm formas recursivas.
JdeBP

Respostas:

19

Existem várias possibilidades:

  • Use uma porta de um touchcomando Unix e simplesmente combine finde touchda maneira Unix. Existem várias opções. Freqüentemente mencionados são GNUWin32 , cygwin e unxutils . Menos conhecidas, mas de certa forma melhores, são as ferramentas no kit de ferramentas do utilitário SFUA , que são executadas no Subsistema para Aplicativos Baseados em UNIX, que vem logo ali na caixa com o Windows 7 Ultimate edition e o Windows Server 2008 R2. (No Windows XP, é possível baixar e instalar o Services for UNIX versão 3.5 .) Este kit de ferramentas possui um grande número de ferramentas TUI de linha de comando, de mve du, através dos shells Korn e C, paraperle awk. Ele vem nos sabores x86-64 e IA64, bem como no x86-32. Os programas são executados no ambiente POSIX nativo e adequado do Windows, em vez de com DLLs de emulador (como cygwin1.dll) sobrepor coisas no Win32. E sim, o kit de ferramentas tem touche find, assim como outras 300 outras.
    Todos esses kits de ferramentas têm a conhecida desvantagem de executar um processo separado para cada arquivo a ser tocado, é claro. Isso não é um problema com as seguintes alternativas.

  • Use um dos muitos touchcomandos nativos do Win32 que as pessoas escreveram e publicaram. Muitos deles suportam opções para executar recursão, sem a necessidade de um Unix findenvolvê-los. (Afinal, eles estão alvejando uma base de usuários que procura um touchcomando, porque ele não possui toda uma carga de comandos do Unix portados.) Um deles é o Stéphane Duguay,touch que, como você pode ver, tem uma --recursiveopção.

  • Seja esperto com os misteriosos mistérios do CMD. Como mencionado na outra resposta, COPY /B myfile+,,atualizará o carimbo de data da última modificação de um arquivo, usando a sintaxe "plus" pouco conhecida do COPYcomando (mais sobre isso pode ser encontrado aqui , aliás). É claro que isso pode ser combinado com FOR /Ra execução recursiva da operação, como sugerido em outra resposta aqui.

  • Use um intérprete de comando de substituição e seja menos inteligente e mais direto que o CMD. O TCC / LE da JP Software é um desses. Ele adiciona uma /Sopção ao seu COPYcomando , o que significa que é possível usar COPY /Scom a sintaxe "mais" para eliminar a necessidade de um FORwrapper. Mas isso ainda está dificultando a vida desnecessariamente, considerando que o TCC / LE possui um comando TOUCH integrado que suporta diretamente uma /Sopção.

JdeBP
fonte
2
+1, o COPY /B file+,,é o caminho a percorrer, não requer extras ... :-)
Tamara Wijsman
3
The Powershell way:(ls file).LastWriteTime = DateTime.now
Tamara Wijsman 28/02
5

Como eles estão prontamente disponíveis, eu recomendaria aproveitar os unxutils . Eles incluem os comandos finde touchque tornarão isso muito fácil.

Depois de mudar para o diretório superior, você deseja modificar:

encontrar . -type f -exec touch {} +
John T
fonte
5

Para usar apenas a funcionalidade existente do Windows (nada extra para instalar), tente um destes:

forfiles /P C:\Path\To\Root /S /C "cmd /c Copy /B @path+,,"  

(toque "recursivamente" em todos os arquivos que começam no caminho especificado)

OU

forfiles /S /C "cmd /c Copy /B @path+,,"   

(toque "recursivamente" em todos os arquivos que começam no diretório atual)

Sven Roepke
fonte
3
-1 No estado atual, esses comandos copiam arquivos de subpastas para a raiz e o resultado é uma bagunça.
TonyG
11
+1 Uma pequena reviravolta para consertar o que o @TonyG disse: forfiles / S / C "cmd / c Copiar / B nul: + ,,"
Alex Dupuis
não altera a última modificação
beppe9000
4

Sei que provavelmente é um pouco tarde demais, mas, no entanto, deixarei minha resposta caso alguém precise da mesma coisa.

A resposta de John T não funcionou para mim no Windows 7. Depois de algumas pesquisas, encontrei este utilitário chamado SKTimeStamp , que faz o trabalho perfeitamente.

Aqui está um artigo com mais detalhes sobre como ele funciona: http://www.trickyways.com/2009/08/how-to-change-timestamp-of-a-file-in-windows-file-created-modified-and -acessado / .

Aqui estão as etapas que você precisa executar:

  • Instale o aplicativo
  • Vá para o diretório em que você precisava alterar os carimbos de data e hora
  • Pesquise * na caixa de pesquisa para que o explorador mostre todos os arquivos
  • Quando todos os arquivos forem encontrados, selecione todos, clique com o botão direito do mouse neles e escolha Propriedades
  • Na caixa de diálogo, escolha a guia TimeStamps
  • Ajuste suas datas e horários conforme necessário e clique em Touch

Voila! Todos os seus arquivos foram atualizados! Não há necessidade de utilitários unix ou linhas de comando.

Andris
fonte
1

Ou você pode usar as ferramentas já incorporadas no Windows, uma vez que já tenha algum tipo de ferramenta de "toque":

for /r %i in (C:\Path\To\Root\*) do @touch "%i"

OU

forfiles /P C:\Path\To\Root /S /C "touch @file"

(Nota: se você estiver fazendo isso a partir de um arquivo em lotes e quiser usar o forcomando, certifique-se de usar sinais de porcentagem dupla para suas variáveis. (Por exemplo, em %%ivez de %i)

afrazier
fonte
1

Também falhou no Windows 7 para mim. Eu usei uma sintaxe diferente e fiz funcionar:

forfiles /c "cmd /c touch @file"

Observe que não usei a opção recurse.

jemiah
fonte
1

Usando o PowerShell:

C:\> powershell  (ls your-file-name-here).LastWriteTime = Get-Date
ThiagoAlves
fonte
Isso não funciona para mim:The property 'LastWriteTime' cannot be found on this object.
Ben N
Funcionou para mim no Windows Server 2012: (ls. \ Backup_db_20150810.sql) .LastWriteTime = Get-Date
ThiagoAlves
0

Em referência à resposta de John T acima:

Eu estava tentando entender a diferença entre finalizar findo comando exec de um com a \;e um `+ '(eu não sabia do último).

Isso foi útil: ( daqui )

-exec command ;
Executar comando; true se 0 status for retornado. Todos os seguintes argumentos a serem encontrados são considerados argumentos para o comando até um argumento que consiste em ';' é encontrado. A string '{}' é substituída pelo nome do arquivo atual sendo processado em todos os lugares em que ocorre nos argumentos do comando, não apenas nos argumentos em que está sozinho, como em algumas versões do find.

-exec command {} +
Essa variante da ação -exec executa o comando especificado nos arquivos selecionados, mas a linha de comandos é criada anexando cada nome de arquivo selecionado no final; o número total de invocações do comando será muito menor que o número de arquivos correspondentes. A linha de comando é construída da mesma maneira que o xargs cria suas linhas de comando. Somente uma instância de '{}' é permitida dentro do comando. O comando é executado no diretório inicial.

Considere uma pasta c:\myfoldercontendo 2 arquivos a.txteb.txt

  1. find . -type f -exec touch {} +é interpretado como:
    touch a.txt b.txt
    Isso é semelhante ao modo como o xargs funciona

  2. considerando que find . -type f -exec touch {} \;é interpretado como:
    touch a.txt
    touch b.txt

Portanto, o número 1 é muito mais rápido (mas também sofre com a limitação de que o comando a seguir execpode ter apenas um {}espaço reservado).

Ashutosh Jindal
fonte
Ótimo comentário com boas informações, mas não uma resposta para a pergunta. Marcaria com +1 se este fosse um comentário.
TonyG
11
:) Eu não tenho nenhuma memória de fazer este post :)
Ashutosh Jindal
0

Usando o PowerShell para o diretório atual e todos os subdiretórios:

dir -R | foreach { $_.LastWriteTime = [System.DateTime]::Now }

Ou você pode especificar uma pasta logo depois dir.

icl7126
fonte