Me gustaría saber cómo recorrer cada línea en un archivo de texto usando un archivo por lotes de Windows y procesar cada línea de texto en sucesión.
Me gustaría saber cómo recorrer cada línea en un archivo de texto usando un archivo por lotes de Windows y procesar cada línea de texto en sucesión.
Respuestas:
Las publicaciones a continuación ayudaron enormemente, pero no hicieron lo que dije en mi pregunta, donde necesitaba procesar toda la línea en su conjunto. Esto es lo que encontré para trabajar.
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
La palabra clave de tokens con un asterisco (*) extraerá todo el texto de toda la línea. Si no coloca el asterisco, solo extraerá la primera palabra de la línea. Supongo que tiene que ver con espacios.
Agradezco todas las publicaciones!
Si hay espacios en la ruta del archivo, debe usarlos usebackq
. Por ejemplo.
for /F "usebackq tokens=*" %%A in ("my file.txt") do [process] %%A
for /F "tokens=*" %%A in ("myfile.txt") do echo A = %%A
-> A = myfile.txt
. ¿Alguna idea de cómo frustrar esto?
De la referencia de línea de comando de Windows:
Para analizar un archivo, ignorando las líneas comentadas, escriba:
for /F "eol=; tokens=2,3* delims=," %i in (myfile.txt) do @echo %i %j %k
Este comando analiza cada línea en Myfile.txt, ignorando las líneas que comienzan con un punto y coma y pasan el segundo y tercer token de cada línea al cuerpo FOR (los tokens están delimitados por comas o espacios). El cuerpo de la instrucción FOR hace referencia a% i para obtener el segundo token,% j para obtener el tercer token y% k para obtener todos los tokens restantes.
Si los nombres de archivo que proporciona contienen espacios, utilice comillas alrededor del texto (por ejemplo, "Nombre de archivo"). Para usar comillas, debe usar usebackq. De lo contrario, las comillas se interpretan como la definición de una cadena literal para analizar.
Por cierto, puede encontrar el archivo de ayuda de línea de comandos en la mayoría de los sistemas Windows en:
"C:\WINDOWS\Help\ntcmds.chm"
En un archivo por lotes DEBE usar en %%
lugar de %
: (Tipo help for
)
for /F "tokens=1,2,3" %%i in (myfile.txt) do call :process %%i %%j %%k
goto thenextstep
:process
set VAR1=%1
set VAR2=%2
set VAR3=%3
COMMANDS TO PROCESS INFORMATION
goto :EOF
Qué hace esto: El "do call: process %% i %% j %% k" al final del comando for pasa la información adquirida en el comando for desde myfile.txt a la "subrutina" del proceso.
Cuando usa el comando for en un programa por lotes, debe usar signos de% doble para las variables.
Las siguientes líneas pasan esas variables del comando for al proceso 'subrutina' y le permiten procesar esta información.
set VAR1=%1
set VAR2=%2
set VAR3=%3
Tengo algunos usos bastante avanzados de esta configuración exacta que estaría dispuesto a compartir si se necesitan más ejemplos. Agregue su EOL o Delims según sea necesario, por supuesto.
Mejorando la primera respuesta "FOR / F ..": Lo que tuve que hacer fue llamar a ejecutar cada script que figura en MyList.txt, por lo que funcionó para mí:
for /F "tokens=*" %A in (MyList.txt) do CALL %A ARG1
O bien, si desea hacerlo a través de la línea múltiple:
for /F "tokens=*" %A in (MuList.txt) do (
ECHO Processing %A....
CALL %A ARG1
)
Editar: El ejemplo anterior es para ejecutar el bucle FOR desde el símbolo del sistema; desde un script por lotes, se debe agregar un% adicional, como se muestra a continuación:
---START of MyScript.bat---
@echo off
for /F "tokens=*" %%A in ( MyList.TXT) do (
ECHO Processing %%A....
CALL %%A ARG1
)
@echo on
;---END of MyScript.bat---
La respuesta de @ MrKraus es instructiva. Además, permítame agregar que si desea cargar un archivo ubicado en el mismo directorio que el archivo por lotes, prefije el nombre del archivo con% ~ dp0. Aquí hay un ejemplo:
cd /d %~dp0
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
NB:: si su nombre de archivo o directorio (por ejemplo, myfile.txt en el ejemplo anterior) tiene un espacio (por ejemplo, 'mi archivo.txt' o 'c: \ Archivos de programa'), use:
for /F "tokens=*" %%A in ('type "my file.txt"') do [process] %%A
, con la palabra clave type que llama al type
programa, que muestra el contenido de un archivo de texto. Si no desea sufrir la sobrecarga de llamar al comando de tipo, debe cambiar el directorio al directorio del archivo de texto. Tenga en cuenta que el tipo aún es necesario para los nombres de archivos con espacios.
¡Espero que esto ayude a alguien!
**cd /d %~dp0**
antes del ciclo for. Esto aseguraría que está haciendo referencia a un archivo en el directorio en el que se encuentra el archivo por lotes. Gracias por la observación
type
walkaround
type
evitar que funcione, tuve que citar mi nombre de archivo porque está en un directorio diferente que contiene espacios (Maldición Program Files
). Recibo un errorThe system cannot find the file `type.
La respuesta aceptada es buena, pero tiene dos limitaciones.
Cae líneas vacías y líneas que comienzan con;
Para leer líneas de cualquier contenido, necesita la técnica de alternancia de expansión retrasada.
@echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ text.txt"`) do (
set "var=%%a"
SETLOCAL EnableDelayedExpansion
set "var=!var:*:=!"
echo(!var!
ENDLOCAL
)
Findstr se usa para prefijar cada línea con el número de línea y dos puntos, para que las líneas vacías ya no estén vacías.
DelayedExpansion debe deshabilitarse cuando se accede al %%a
parámetro; de lo !
contrario ^
, se perderán los signos de exclamación y las marcas , ya que tienen significados especiales en ese modo.
Pero para eliminar el número de línea de la línea, la expansión demorada debe estar habilitada.
set "var=!var:*:=!"
elimina todo hasta el primer colon (el uso delims=:
eliminaría también todos los dos puntos al comienzo de una línea, no solo el de los hallazgos).
El endlocal desactiva la expansión demorada nuevamente para la siguiente línea.
La única limitación es ahora el límite de longitud de línea de ~ 8191, pero parece que no hay forma de superar esto.
setlocal
en la línea de comandos. Cuando ejecuto código en CMD, obtengo! Var! en lugar de espacios en blanco. ¿Como arreglar?
Aquí hay un archivo bat que escribí para ejecutar todos los scripts SQL en una carpeta:
REM ******************************************************************
REM Runs all *.sql scripts sorted by filename in the current folder.
REM To use integrated auth change -U <user> -P <password> to -E
REM ******************************************************************
dir /B /O:n *.sql > RunSqlScripts.tmp
for /F %%A in (RunSqlScripts.tmp) do osql -S (local) -d DEFAULT_DATABASE_NAME -U USERNAME_GOES_HERE -P PASSWORD_GOES_HERE -i %%A
del RunSqlScripts.tmp
Si usted tiene un NT-familia Windows (uno con cmd.exe
como la cáscara), tratar el comando for / F .
La respuesta aceptada usando cmd.exe
y
for /F "tokens=*" %F in (file.txt) do whatever "%F" ...
funciona solo para archivos "normales". Falla miserablemente con archivos enormes.
Para archivos grandes, puede que necesite usar Powershell y algo como esto:
[IO.File]::ReadLines("file.txt") | ForEach-Object { whatever "$_" }
o si tienes suficiente memoria:
foreach($line in [System.IO.File]::ReadLines("file.txt")) { whatever "$line" }
Esto funcionó para mí con un archivo de 250 MB que contiene más de 2 millones de líneas, donde el for /F ...
comando se atascó después de unos pocos miles de líneas.
Para conocer las diferencias entre foreach
y ForEach-Object
, consulte Introducción a ForEach y ForEach-Object .
(créditos: Leer archivo línea por línea en PowerShell )
Ejemplos modificados aquí para enumerar nuestras aplicaciones Rails en Heroku, ¡gracias!
cmd /C "heroku list > heroku_apps.txt"
find /v "=" heroku_apps.txt | find /v ".TXT" | findstr /r /v /c:"^$" > heroku_apps_list.txt
for /F "tokens=1" %%i in (heroku_apps_list.txt) do heroku run bundle show rails --app %%i
Código completo aquí .
for /f "tokens=1" %%i in ('find /v "=" heroku_apps.txt ^| find /v ".TXT" ^| findstr /r /v /c:"^$"') do...
( ^
tenga en cuenta la adición de 's utilizado para escapar de la tubería, para que se pase al for
procesador de comandos y no directamente al procesador de comandos)
Para imprimir todas las líneas en el archivo de texto desde la línea de comando (con expansión retardada):
set input="path/to/file.txt"
for /f "tokens=* delims=[" %i in ('type "%input%" ^| find /v /n ""') do (
set a=%i
set a=!a:*]=]!
echo:!a:~1!)
Funciona con espacios en blanco iniciales, líneas en blanco, líneas de espacios en blanco.
Probado en Win 10 CMD
]]]
líneas de entrada, la segunda muestra suelta líneas vacías y líneas que comienzan con espacio
delims
si alguna línea en el archivo de texto comienza con, ]
por ejemplo. reemplace con algún personaje que no lo haga, o un personaje de control como retroceso o campana; normalmente no se encuentran en archivos de texto. La razón de delims=]
es eliminar los marcadores de posición creadas por /n
de find
comando para preservar las líneas en blanco.
%%A
con%A
el comando anterior. De lo contrario lo conseguirás%%A was unexpected at this time.
.