Pregunta

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

  • Mostrar el nombre base 'f'
  • Realizar una acción en 'f.in'
  • Realizar otra acción en 'f.out'

No tengo ninguna forma de enumerar el conjunto de nombres de archivos base, aparte de buscar *.in (o *.out), por ejemplo.

¿Fue útil?

Solución

Suponiendo que tiene dos programas 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 solo a un nombre de archivo.Ver otros modificadores en https://technet.microsoft.com/en-us/library/bb490909.aspx (a mitad de la página) o simplemente en la siguiente respuesta.

Otros consejos

Puede utilizar esta línea para imprimir el contenido de su escritorio:

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

Una vez que tengas el %%I variable, es fácil ejecutar un comando en ella (simplemente reemplace la palabra echo con su programa)

Además, se ha mejorado la sustitución de referencias variables, ahora puede usar la siguiente sintaxis 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 la ruta puede ser reemplazada por otros valores válidos.El %~ la sintaxis termina con un nombre de variable FOR válido.Elegir nombres de variables en mayúsculas como %I lo hace más legible y evita la confusión con los modificadores, que no son sensibles a las minas.

Puede obtener la documentación completa escribiendo FOR /?

La forma más fácil, a mi modo de ver, es utilizar un bucle for que llame a un segundo archivo por lotes para su procesamiento y le pase a ese segundo archivo el nombre base.

Según el para /?ayuda, el nombre base se puede extraer usando la ingeniosa opción ~n.Entonces, el script base diría:

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

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

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

Puede que haya una mejor manera de hacer esto en un solo script, pero siempre he estado un poco confuso sobre cómo extraer múltiples comandos en un solo bucle for en un archivo por lotes.

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

Hay una herramienta que generalmente se usa en servidores MS (hasta donde puedo recordar) llamada archivos:

El enlace anterior contiene ayuda y un enlace a la página de descarga de Microsoft.

Ampliando natanas correo.Lo siguiente hará el lote de 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 los nombres de archivos que comienzan con la subcadena determinada.Se podría cambiar para adaptarlo a diferentes necesidades trabajando en la extracción de subcadenas de subfname y la declaración 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

Hacer eco de f.in y f.out separará el concepto de qué bucle y qué no bucle cuando se utiliza 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 preguntaste, una buena manera 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

Pido disculpas si no respondí esto correctamente.La pregunta me resultó muy difícil de leer.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top