Comando táctil recursivo de Windows

17

En Windows 7, ¿cómo puedo tocar recursivamente todos los archivos en un directorio (incluidos los subdirectorios) para actualizar la marca de fecha / hora?

¿Windows 7 tiene un mecanismo para lograr esto?

jmq
fuente
posible duplicado del equivalente
Pausado hasta nuevo aviso.
La respuesta "aceptada" en ese enlace es sobre el uso de bibliotecas de programación .NET para lograr eso para un archivo. Los otros trataban de agregar un menú contextual para actualizar archivos individuales. Estaba buscando un comando integrado para hacerlo en N archivos de forma recursiva. La respuesta a continuación funcionó para hacerlo para todos los archivos. No está integrado, pero funciona. Gracias.
jmq
Tampoco es un duplicado de la versión de Windows del comando táctil Unix , porque esta pregunta es específicamente para la recurrencia. Sin embargo, tenga en cuenta que algunas respuestas a esa pregunta tienen formas recursivas.
JdeBP

Respuestas:

19

Hay varias posibilidades:

  • Use un puerto de un touchcomando Unix y simplemente combine findy touchde la manera Unix. Hay varias opciones Los mencionados anteriormente son GNUWin32 , cygwin y unxutils . Menos conocidas, pero de alguna manera mejores, son las herramientas en el kit de herramientas de utilidad SFUA , que se ejecutan en el Subsistema para aplicaciones basadas en UNIX que viene en la caja con Windows 7 Ultimate Edition y Windows Server 2008 R2. (Para Windows XP, uno puede descargar e instalar Servicios para UNIX versión 3.5 .) Este kit de herramientas tiene una gran cantidad de herramientas TUI de línea de comandos, desde mvy du, a través de los shells Korn y C, hastaperly awk. Viene en sabores x86-64 e IA64, así como en x86-32. Los programas se ejecutan en el entorno POSIX apropiado nativo de Windows, en lugar de con archivos DLL de emulador (como cygwin1.dll) superponer cosas sobre Win32. Y sí, el kit de herramientas tiene touchy find, además de unos 300 más.
    Todos estos juegos de herramientas tienen la conocida desventaja de ejecutar un proceso separado para cada archivo que se toque, por supuesto. Eso no es un problema con las siguientes alternativas.

  • Utilice uno de los muchos touchcomandos nativos de Win32 que la gente ha escrito y publicado. Muchos de ellos admiten opciones para realizar la recursividad, sin la necesidad de que Unix los findenvuelva. (Después de todo, están apuntando a una base de usuarios que está buscando un touchcomando porque no tiene una carga completa de comandos Unix portados). Uno de ellos es Stéphane Duguay,touch que como puede ver tiene una --recursiveopción.

  • Sé inteligente con los misterios arcanos de CMD. Como se menciona en la otra respuesta, COPY /B myfile+,,actualizará la fecha de la última modificación de un archivo, utilizando la sintaxis "más" poco conocida del COPYcomando (más información sobre la cual se puede encontrar aquí , por cierto). Esto, por supuesto, se puede combinar FOR /Rpara realizar la operación de forma recursiva, como se sugiere en otra respuesta aquí.

  • Use un intérprete de comandos de reemplazo y sea menos inteligente y más directo que CMD. JP Software TCC / LE es uno de esos. Agrega una /Sopción a su COPYcomando , lo que significa que se podría usar COPY /Scon la sintaxis "plus" para eliminar la necesidad de un FORcontenedor. Pero eso realmente todavía hace la vida innecesariamente difícil para uno mismo, teniendo en cuenta que TCC / LE tiene un comando TOUCH incorporado que admite directamente una /Sopción.

JdeBP
fuente
2
+1, este COPY /B file+,,es el camino a seguir, no requiere extras ... :-)
Tamara Wijsman
3
La manera Powershell:(ls file).LastWriteTime = DateTime.now
Tamara Wijsman
5

Como están fácilmente disponibles, recomendaría aprovechar los unxutils . Incluyen los comandos findy touchque lo harán muy fácil.

Después de cambiar al directorio superior que desea modificar:

encontrar . -tipo f -exec táctil {} +
John T
fuente
5

Para usar solo la funcionalidad de Windows existente (nada extra para instalar) intente uno de estos:

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

("tocar" recursivamente todos los archivos que comienzan en la ruta especificada)

O

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

("tocar" recursivamente todos los archivos que comienzan en el directorio actual)

Sven Roepke
fuente
3
-1 Como está, estos comandos copian archivos de subcarpetas a la raíz y el resultado es un desastre.
TonyG
1
+1 Un pequeño giro para arreglar lo que @TonyG dijo: forfiles / S / C "cmd / c Copy / B nul: + ,,"
Alex Dupuis el
no cambia última modificación
beppe9000
4

Sé que esto probablemente sea demasiado tarde, pero no obstante, dejaré mi respuesta en caso de que alguien más necesite lo mismo.

La respuesta de John T no funcionó para mí en Windows 7. Después de investigar, encontré esta utilidad llamada SKTimeStamp , que hace el trabajo perfectamente.

Aquí hay un artículo con más detalles sobre cómo funciona: http://www.trickyways.com/2009/08/how-to-change-timestamp-of-a-file-in-windows-file-created-modified-and -accedido / .

Estos son los pasos que debe realizar:

  • Instala la aplicación
  • Vaya al directorio donde necesitaba cambiar las marcas de tiempo
  • Busque * en el cuadro de búsqueda para que el explorador muestre todos los archivos
  • Cuando encuentre todos los archivos, selecciónelos todos, haga clic derecho sobre ellos y elija Propiedades
  • En el diálogo, elija la pestaña Sellos de tiempo
  • Ajuste sus fechas y horas según sea necesario y haga clic en Toque

Voila! ¡Todos tus archivos han sido actualizados! No se necesitan utilidades ni líneas de comando de Unix.

Andris
fuente
1

O podría usar las herramientas ya integradas en Windows, una vez que ya tenga una herramienta "táctil" de algún tipo:

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

O

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

(Nota: si está haciendo esto desde un archivo por lotes y desea usar el forcomando, asegúrese de usar signos de doble porcentaje para sus variables. (Por ejemplo, en %%ilugar de %i)

afrazier
fuente
1

También falló en Windows 7 para mí. Utilicé una sintaxis diferente y la hice funcionar:

forfiles /c "cmd /c touch @file"

Tenga en cuenta que no utilicé la opción recurse.

jemiah
fuente
1

Usando powershell:

C:\> powershell  (ls your-file-name-here).LastWriteTime = Get-Date
ThiagoAlves
fuente
Esto no funciona para mí:The property 'LastWriteTime' cannot be found on this object.
Ben N
Me funcionó en Windows Server 2012: (ls. \ Backup_db_20150810.sql) .LastWriteTime = Get-Date
ThiagoAlves
0

En referencia a la respuesta de John T arriba:

Estaba tratando de entender la diferencia entre terminar findel comando exec de un con a \;y un '+' (no sabía de este último).

Esto fue útil: (desde aquí )

-exec command ;
Ejecutar comando; verdadero si se devuelve el estado 0. Todos los siguientes argumentos para encontrar se consideran argumentos del comando hasta que un argumento que consista en ';' se encuentra La cadena '{}' se reemplaza por el nombre del archivo actual que se procesa en todas partes donde aparece en los argumentos del comando, no solo en los argumentos donde está solo, como en algunas versiones de find.

-exec command {} +
Esta variante de la acción -exec ejecuta el comando especificado en los archivos seleccionados, pero la línea de comando se crea agregando cada nombre de archivo seleccionado al final; El número total de invocaciones del comando será mucho menor que el número de archivos coincidentes. La línea de comando se construye de la misma manera que xargs construye sus líneas de comando. Solo se permite una instancia de '{}' dentro del comando. El comando se ejecuta en el directorio de inicio.

Considere una carpeta que c:\myfoldercontiene 2 archivos a.txtyb.txt

  1. find . -type f -exec touch {} +se interpreta como:
    touch a.txt b.txt
    Esto es similar a la forma en que funciona xargs

  2. mientras que find . -type f -exec touch {} \;se interpreta como:
    touch a.txt
    touch b.txt

Por lo tanto, el n. ° 1 es mucho más rápido (pero también adolece de la limitación de que el siguiente comando execsolo puede tener un {}marcador de posición).

Ashutosh Jindal
fuente
Gran comentario con buena información, pero no una respuesta a la pregunta. Tendría +1 si esto fuera un comentario.
TonyG
1
:) No recuerdo haber hecho esta publicación :)
Ashutosh Jindal
0

Usando PowerShell para el directorio actual y todos los subdirectorios:

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

O puede especificar una carpeta justo después dir.

icl7126
fuente