Cómo recorrer los archivos que coinciden con el comodín en el archivo por lotes

Tengo un conjunto de nombres de archivo base, para cada nombre ‘f’ hay exactamente dos archivos, ‘f.in’ y ‘f.out’. Quiero escribir un archivo por lotes (en Windows XP) que recorre todos los nombres de archivo, para cada uno debería:

  • Mostrar el nombre base ‘f’
  • Realiza una acción en ‘f.in’
  • Realice otra acción en ‘f.out’

No tengo forma de listar el conjunto de nombres de archivo base, excepto buscar * .in (o * .out) por ejemplo.

Suponiendo que tiene dos progtwigs que procesan los dos archivos, process_in.exe y process_out.exe:

for %%f in (*.in) do ( echo %%~nf process_in "%%~nf.in" process_out "%%~nf.out" ) 

%% ~ nf es un modificador de sustitución, que expande% f a un nombre de archivo solamente. Vea otros modificadores en https://technet.microsoft.com/en-us/library/bb490909.aspx (en la mitad de la página) o simplemente en la próxima respuesta.

Puede usar esta línea para imprimir los contenidos de su escritorio:

 FOR %%I in (C:\windows\desktop\*.*) DO echo %%I 

Una vez que tiene la variable %%I es fácil ejecutar un comando (simplemente reemplace la palabra echo con su progtwig)

Además, se ha mejorado la sustitución de las referencias de variables FOR. Ahora puede usar la siguiente syntax opcional:

 %~I - expands %I removing any surrounding quotes (") %~fI - expands %I to a fully qualified path name %~dI - expands %I to a drive letter only %~pI - expands %I to a path only (directory with \) %~nI - expands %I to a file name only %~xI - expands %I to a file extension only %~sI - expanded path contains short names only %~aI - expands %I to file attributes of file %~tI - expands %I to date/time of file %~zI - expands %I to size of file %~$PATH:I - searches the directories listed in the PATH environment variable and expands %I to the fully qualified name of the first one found. If the environment variable name is not defined or the file is not found by the search, then this modifier expands to the empty string [https://ss64.com/nt/syntax-args.html][1] 

En los ejemplos anteriores, %I y PATH pueden ser reemplazados por otros valores válidos. La syntax %~ finaliza con un nombre de variable FOR válido. Escoger mayúsculas y minúsculas como %I hace más legible y evita confusiones con los modificadores, que no distinguen entre mayúsculas y minúsculas.

Puede obtener la documentación completa escribiendo FOR /?

La manera más fácil, como lo veo, es usar un bucle for que llama a un segundo archivo por lotes para procesar, pasando ese segundo archivo al nombre base.

De acuerdo con el for /? ayuda, el nombre base se puede extraer usando la ingeniosa opción n. Entonces, el script base leería:

 for %%f in (*.in) do call process.cmd %%~nf 

Luego, en process.cmd, supongamos que% 0 contiene el nombre base y actúa en consecuencia. Por ejemplo:

 echo The file is %0 copy %0.in %0.out ren %0.out monkeys_are_cool.txt 

Puede haber una mejor manera de hacer esto en un script, pero siempre he sido un poco confuso sobre cómo extraer de varios comandos en un único bucle for en un archivo por lotes.

EDITAR: ¡Eso es fantástico! De alguna manera me había perdido la página en los documentos que mostraba que se podían hacer bloques de varias líneas en un ciclo FOR. Voy a tener que volver y volver a escribir algunos archivos por lotes ahora …

Hay una herramienta generalmente utilizada en servidores MS (por lo que puedo recordar) llamada archivos forzados :

El enlace de arriba contiene ayuda, así como un enlace a la página de descarga de microsoft.

Ampliando la publicación de Nathans . Lo siguiente hará la porción del trabajo en un archivo por lotes.

 @echo off if %1.==Sub. goto %2 for %%f in (*.in) do call %0 Sub action %%~nf goto end :action echo The file is %3 copy %3.in %3.out ren %3.out monkeys_are_cool.txt :end 

El siguiente código filtra nombres de archivos que comienzan con una subcadena dada. Se podría cambiar para adaptarse a diferentes necesidades trabajando en la extracción de subcadenas de subcadenas y en la statement IF:

 echo off rem filter all files not starting with the prefix 'dat' setlocal enabledelayedexpansion FOR /R your-folder-fullpath %%F IN (*.*) DO ( set fname=%%~nF set subfname=!fname:~0,3! IF NOT "!subfname!" == "dat" echo "%%F" ) pause 

Haciendo eco de f.in y f.out se separará el concepto de qué bucle y qué no bucle cuando se usa en un bucle for / f.

 ::Get the files seperated echo f.in>files_to_pass_through.txt echo f.out>>files_to_pass_through.txt for /F %%a in (files_to_pass_through.txt) do ( for /R %%b in (*.*) do ( if "%%a" NEQ "%%b" ( echo %%b>>dont_pass_through_these.txt ) ) ) ::I'm assuming the base name is the whole string "f". ::If I'm right then all the files begin with "f". ::So all you have to do is display "f". right? ::But that would be too easy. ::Let's do this the right way. for /f %%C in (dont_pass_through_these.txt) ::displays the filename and not the extention echo %~nC ) 

Aunque no lo haya preguntado, una buena forma de pasar comandos a f.in y f.out sería …

 for /F %%D "tokens=*" in (dont_pass_through_these.txt) do ( for /F %%E in (%%D) do ( start /wait %%E ) ) 

Un enlace a todos los comandos de Windows XP: enlace

Me disculpo si no respondí esto correctamente. La pregunta fue muy difícil de leer.