2008-09-02 27 views
154

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 pasa por todos los nombres de ficheros, para cada uno debería:Cómo recorrer los archivos que coinciden con el comodín en el archivo de proceso por lotes

  • mostrar el nombre de la base 'f'
  • realizar una acción en 'f.in'
  • realizar otra acción en 'f.out'

no tengo ninguna manera de enumerar el conjunto de nombres de archivo comunes, excepto para buscar * .in (o * .out) por ejemplo.

+7

Realmente no quiero ser este tipo después de 111/0 votos, pero su pregunta no muestra ninguna investigación whatsoeaver – Blauhirn

Respuesta

234

Asumiendo 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 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.

+28

Use a solo '%' si escribe esto en la línea de comando. Sé que OP no pregunta por la línea de comandos, pero eso es lo que estaba buscando cuando surgió esta pregunta en la parte superior de mi búsqueda en Google. Otros pueden apreciar este bit. – Jason

+1

¿Podría explicar la sintaxis? La variable de ciclo se declara '%% f' ¿por qué' '%% ~ nf' después? –

+3

@ColonelPanic - hay un puñado de modificadores '~' para hacer cosas, como en mi ejemplo, simplemente obtenga el nombre del archivo. Es un hábito para mí usar eso en caso de que el '*' haga la ruta completa o algo así. Hay un puñado de estos modificadores (en la mitad de la página): http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/batch.mspx?mfr=true –

4

La manera más fácil, según lo veo, es utilizar un bucle for que llama a un segundo archivo por lotes para su procesamiento, pasando ese segundo archivo al nombre base.

Según el for /? ayuda, el nombre base se puede extraer usando la ingeniosa opción n. Por lo tanto, la secuencia de comandos de base sería el siguiente:

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

Luego, en process.cmd, se supone que 0% contiene el nombre de la base y actuar 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 una secuencia de comandos, pero yo siempre he sido un poco nebuloso sobre cómo tirar de varios comandos en un solo bucle 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 ir tienen que volver atrás y volver a escribir algunos archivos por lotes ahora ...

3

Hay una herramienta normalmente utilizado en servidores MS (por lo que yo puedo recordar) llamada forfiles:

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

68

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

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

Una vez que tenga la variable %%I que es fácil de ejecutar un comando en él (basta con sustituir la palabra eco con su programa)

Además, la sustitución de las referencias variables se ha mejorado ahora puede utilizar 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 PATH se pueden reemplazar por otros valores válidos. La sintaxis %~ finaliza con un nombre de variable FOR válido. Seleccionar nombres de mayúsculas como %I lo hace más legible y evita confusiones con los modificadores, que no distinguen entre mayúsculas y minúsculas.

, usted puede obtener la documentación completa escribiendo FOR /?

+0

Esto no parece funcionar. '%% Yo era inesperado en este momento. – Brad

+2

@Brad si está usando esto en la línea de comandos (y no en un archivo por lotes), luego use'% I' en lugar de '%% I' – doubleDown

3

Expandir en Nathans publicar. 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 
0

El siguiente código filtra los nombres de archivo que comienzan con una subcadena determinada. Podría ser cambiado para adaptarse a diferentes necesidades, trabajando en la extracción subfname subcadena y la instrucció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 
0

Haciendo eco f.in y f.out separará el concepto de lo que debe y lo que no bucle de bucle cuando se utiliza en una para/f loop.

::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 usted no pidió, una buena manera de pasar comandos en 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: link

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

Cuestiones relacionadas