4 votos

Busque el archivo más reciente en un directorio y copie la carpeta que lo contiene en otro directorio

En mi directorio tengo muchos archivos con el mismo nombre también en muchos otros subdirectorios

estructura de archivos de ejemplo:

C: \ a \ first \ hello.txt
C: \ a \ second \ hello.txt
C: \ a \ tercero \ hello.txt

Necesito buscar específicamente el 'hello.txt' modificado más recientemente (ya que también hay otros archivos en el directorio) y copiar su carpeta contenedora en C: \ b

Soy muy nuevo en el lote así que las explicaciones serían fantásticas :)

2voto

K7AAY Puntos 1214

Este es un torpe colección de comandos, y no hay duda de que alguien más inteligente que yo (exempli gratia) va a convertir esto en algo mucho más pequeño y más concisa, pero a veces es mejor, mientras que aprender a ver todos los engranajes girando.

Este archivo de proceso por lotes, o 'script', se basa en la corte, la cabeza, y la sed del Núcleo de Utilidades para Windows (Open Source) http://gnuwin32.sourceforge.net/packages/coreutils.htm que, si quieres hacer cualquier tipo de archivo de proceso por lotes de la escritura, hace que su vida sooooo mucho más fácil.

C:      
cd \a  
del temp.tmp  
for /f "eol=: delims=" %%F in ('dir hello.txt /b /s') do @echo %%~tF %%F >> temp.tmp  
sort /r temp.tmp > result.tmp   
head -1 result.tmp > temp.tmp  
cut -d: -f 3 temp.tmp | sed s/hello.txt// > temp.tmp  
set /p SOU=<temp.tmp  
CD %SOU%  
copy *.* C:\b\ 
dir c:\b 

LO que dicen? He aquí un pequeño comentario, a partir de la cuarta línea, que he adaptado (programadores rara vez dicen robó) de la obra de un genio en StackOverflow:

for /f "eol=: delims=" %%F in ('dir hello.txt /b /s') do @echo %%~tF %%F >> temp.tmp

que crea un archivo de trabajo, denominada temp.tmp, construido línea por línea, la lista de todas las hello.txt archivo en el directorio actual; cada línea comienza con la fecha y la hora de hello.txt seguido por una ruta de acceso absoluta a hello.txt que se parece a

10/05/2018 09:27 C:\a\1\hello.txt
10/05/2018 09:29 C:\a\2\hello.txt
10/05/2018 09:32 C:\a\3\hello.txt

sort /r temp.tmp > result.tmp  

toma el contenido de temp.tmp y los ordena en orden inverso, escrito en el resultado.tmp, sobreescribiendo lo que había antes (si hay algo), o crear el archivo si no existe ningún resultado.tmp, produciendo:

10/05/2018 09:32 C:\a\3\hello.txt
10/05/2018 09:29 C:\a\2\hello.txt
10/05/2018 09:27 C:\a\1\hello.txt

head -1 result.tmp > temp.tmp  

hace algo de Windows no sabes cómo hacerlo, así que tenía que conseguir que la libre de-como-en-la cerveza de código Abierto GNU Core Utilities paquete para obtener la cabeza de comando, que aquí sólo toma la primera línea de resultado.tmp y lo escribe en temp.tmp, sobreescribiendo todo lo que había en temp.tmp antes (el único > 'cambio de dirección' operador sobrescribe; el >> operador concatena, añadiendo a lo que ya estaba en el archivo) que nos da:

10/05/2018 09:32 C:\a\3\hello.txt

cut -d: -f 3 temp.tmp | sed s/hello.txt// > temp.tmp  

Esta línea utiliza cortar a echo sólo el tercer campo (la omisión de la fecha y la hora) de temp.tmp y 'los tubos' a otro pequeño programa, de sed, que es tan increíblemente impresionante que las meras palabras no pueden explicar todo lo que puede hacer. Aquí la usamos para encontrar hello.txt y quitar de lo que hemos encontrado en la temp.tmp, y enviarlo a sobrescribir temp.tmp; ahora sólo contiene la ruta de acceso donde el más reciente ejemplo de hello.txt fue, a saber:

\a\3\

(Si desea, puede consolidar las líneas 5, 6, y 7 en uno con

sort /r temp.tmp | head -1 | cut -d: -f 3 | sed s/hello.txt// > temp.tmp 

pero he mantenido separados aquí para los propósitos de enseñanza.)

OK, ahora vamos a la ruta absoluta al directorio de los archivos que desea copiar, sentado en la temp.tmp pero necesitamos que en el archivo de proceso por lotes de modo que con el comando

set /p SOU=<temp.tmp 

hemos establecido una variable, SOU, a lo que en la temp.tmp.

CD %SOU%  

cambia el directorio de trabajo donde el más reciente ejemplo de hello.txt fue, y

copy *.* C:\b\  

copias de sus archivos a \b en la unidad C:

¿Cómo puedo hacer esto? De pie sobre los hombros de gigantes, en su mayoría: yo comencé a saber lo que necesitaba para empezar fue el listado de un directorio de todos los hello.txt archivos, un listado que muestra la fecha y hora de creación para cada archivo seguido por la ruta absoluta. Una vez que tuve, me empezó a picar hacia arriba hasta que llegué a simplemente la más reciente hello.txty tiró todo lo que no era el camino para copiar archivos desde. Un poco como el Esquimeaux escultor que cortar todo lo que no tenía el aspecto de una morsa.

Nota: Cuando se están probando, línea por línea, el uso de una única % para las variables; una vez que las obras y la pones en un archivo de proceso por lotes, se utiliza una doble %%, lo que me confunde mucho, hasta que leí una explicación de mencionarla.

0voto

Meshka7 Puntos 1

Si tiene acceso a bash (posiblemente a través de cygwin, WSL, min-gw, etc.), aquí tiene un liner (asumiendo que ya se encuentra dentro del directorio principal que desea:

 cp $(dirname `find . -type f -exec ls -l {} --time-style=+%s \; | sort -nrk 7 | awk '{print $8}' | head -1`)/* "c:\b"
 

esta asume cygwin. Para otros puede que necesite modificar la ruta de destino ligeramente. Es posible que deba asegurarse primero de que dirname , find , sort , awk , head están disponibles

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: