windows - ¿Por qué el comando ECHO imprime un espacio final adicional en el archivo?
batch-file (3)
Estoy leyendo varias líneas de un archivo de datos y lo agrego a otro archivo. El problema es que hay espacio extra en el archivo de salida al final de las líneas adjuntas. Es obligatorio recortar el espacio final de acuerdo con mis requisitos porque en el archivo de datos original no hay espacio al final de las líneas. Intenté todas las cosas posibles, pero todavía no puedo lograr esto.
@echo off
setlocal enabledelayedexpansion
FOR /F "delims=" %%c IN (C:/Users/184863/Desktop/mydata.txt) DO (
echo %%c>>temp_data.txt
)
endlocal
Opciones que probé:
-
echo %%c>>temp_data.txt
... obteniendo 1 espacio final de línea -
set lines=%%c
echo !lines!>>temp_data.txt
... obteniendo 1 espacio final de línea -
echo !lines:~0,-1!>>temp_data.txt
...echo !lines:~0,-1!>>temp_data.txt
último carácter de la línea -
set lines=!lines: =!
echo !lines!>>temp_data.txt
... todos los espacios dentro de la línea también se recortan (es necesario recortar solo el final de la línea, que no está presente en el archivo de datos original)
Esto debería hacer lo necesario, incluida la necesidad de comentar la línea 100.
Uno: no utilice la expansión retrasada cuando no sea necesario.
Dos: elimine el espacio final en su comando echo.
@(
SETLOCAL
ECHO OFF
SET "_File=C:/Users/184863/Desktop/mydata.txt"
SET "_Count="
SET "_Comment=Your Special Comment "
)
FOR /F "tokens=* delims=" %%c IN (%_File%) DO (
SET /A "Count+=1">NUL
CALL ECHO.[%COUNT%] | FIND "[100]">NUL && (
ECHO:%_Comment%%~c
) || (
ECHO.%%c
)
)>>"%~dp0temp_data.txt"
REM Replace the original file with the commented File
MOVE /Y "%~dp0temp_data.txt" "%_File%"
(
ENDLOCAL
EXIT /B 0
)
Hay un espacio final al final de la línea de
echo
como
ya escribió que no es ignorado por
ECHO
.
ECHO
también genera este espacio final después de
%%c
.
Una redirección generalmente se escribe al final de una línea de comando, pero se puede escribir en cualquier lugar.
También es posible escribir la redirección al principio como se muestra a continuación o en algún lugar en el medio, como se puede ver en la línea de comando
FOR
en
esta respuesta
.
El análisis de una línea de comando de
ECHO
es diferente a todas las demás líneas de comando, ya que un carácter de espacio fuera de una cadena entre comillas dobles no se interpreta como un separador de argumentos y, por esa razón, cada carácter de espacio en la línea de comando de
ECHO
es importante y es emitido por
ECHO,
incluidos los anteriores a los operadores de redirección como
>
.
Esto se puede ver fácilmente por
-
crear un archivo por lotes con solo
echo Test>Test.txt
con un espacio final después deTest.txt
, - abrir una ventana de símbolo del sistema y
- ejecutar este archivo por lotes desde la ventana del símbolo del sistema.
La salida es
echo Test 1>Test.txt
.
Por lo tanto,
>
se reemplaza por el intérprete de comandos de Windows por
1>
(espacio, uno, soporte de ángulo recto) y además se mueve al final de la línea.
Este movimiento en la línea de comando de
ECHO
da como resultado que el espacio original se mueva hacia la izquierda después del texto
Test
y, por lo tanto, también es generado por
ECHO
.
Esta modificación de la línea de comandos durante el preprocesamiento de todo el bloque de comandos también se puede ver ejecutando el código de lote original publicado sin
@echo off
desde una ventana de símbolo del sistema para depurar el archivo por lotes.
El intérprete de comandos de Windows genera
mydata.txt
contiene la línea única
[code=119888#!198; ttps://egrul.nalog.ru/]
[code=119888#!198; ttps://egrul.nalog.ru/]
:
setlocal enabledelayedexpansion
FOR /F "delims=" %c IN (C:/Users/184863/Desktop/mydata.txt) DO (echo %c 1>>temp_data.txt )
(echo [code=119888#!198; ttps://egrul.nalog.ru/] 1>>temp_data.txt )
endlocal
El espacio final después de
>>temp_data.txt
ahora es después de preprocesar toda la línea de comando
FOR
con el bloque de comando que contiene un solo comando a la izquierda para
1>>temp_data.txt
.
Cuando
FOR
ejecuta la línea de comandos de
ECHO
, el espacio final ahora es un espacio adicional entre la línea leída desde
mydata.txt
y
1>>temp_data.txt
también es
1>>temp_data.txt
por
ECHO
.
Siempre se debe tener en cuenta lo que realmente ejecuta el intérprete de comandos de Windows después de preprocesar / analizar una línea de comandos y no lo que está escrito en el archivo por lotes.
Además, la expansión de la variable de entorno retardada está habilitada, lo que da como resultado una lectura de línea del archivo al que se hace referencia con
%%c
procesado por el intérprete de comandos de Windows para
!VariableName!
antes de ejecutar el comando
ECHO
.
Todo entre dos signos de exclamación en línea se interpreta como el nombre de la variable y, por lo tanto, se reemplaza por el valor de la variable referenciada, respectivamente, nada si no existe dicha variable de entorno.
El intérprete de comandos de Windows simplemente elimina un signo de exclamación (restante) durante este procesamiento adicional de la línea antes de la ejecución de
ECHO
.
Solución 1:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "usebackq delims=" %%I in ("%USERPROFILE%/Desktop/mydata.txt") do >>temp_data.txt echo %%I
endlocal
La expansión de la variable de entorno retrasada se deshabilita explícitamente en este código de lote para interpretar los signos de exclamación siempre como caracteres literales.
El archivo de texto con la (s) línea (s) para leer se especifica usando
la variable de entorno de Windows
predefinida
USERPROFILE
entre comillas dobles para trabajar en cualquier computadora con Windows.
Las comillas dobles requieren la opción
usebackq
para obtener la cadena del nombre del archivo con la ruta interpretada como el nombre del archivo de texto desde el cual leer las líneas.
Como una línea quizás termina con un número en el rango del 1 al 9, no es bueno usarla:
echo %%c>>temp_data.txt
Es mejor especificar el operador de redireccionamiento al comienzo de la línea de comando de
ECHO
y especificar a continuación el
echo %%c
sin espacio final.
Lea el artículo de Microsoft sobre el
uso de operadores de redirección de comandos
para obtener más información.
Tenga en cuenta que
FOR
ignora las líneas vacías y también todas las líneas que comienzan con un punto y coma con las opciones utilizadas.
;
es el valor predeterminado para la opción
eol
(final de línea) que no se especifica explícitamente en este archivo por lotes.
Al ejecutar este pequeño archivo por lotes con
@echo off
modificado a
@echo ON
desde una ventana de símbolo del sistema en lugar de hacer doble clic en él, se puede ver lo que el intérprete de comandos de Windows realmente ejecuta:
for /F "usebackq delims=" %I in ("C:/Users/184863/Desktop/mydata.txt") do echo %I 1>>temp_data.txt
echo [code=119888#!198; ttps://egrul.nalog.ru/] 1>>temp_data.txt
Por lo tanto, se puede ver qué línea de comando finalmente ejecuta el intérprete de comandos de Windows después de preprocesar cada línea de comando del archivo por lotes antes de la ejecución.
>>
fue reemplazado por
1>>
(observe el espacio insertado al comienzo) y la redirección al comienzo se movió al final de la línea de comando de
ECHO
.
Solución 2:
@echo off
copy /B temp_data.txt+"%USERPROFILE%/Desktop/mydata.txt" temp_data.txt >nul
El comando
COPIAR
se puede usar para fusionar el contenido de varios archivos especificados con el operador
+
en un solo archivo especificado en último lugar.
Esta característica se usa aquí para agregar a
temp_data.txt
las líneas existentes de
mydata.txt
en el escritorio del usuario.
La opción
/B
(datos binarios) es necesaria para evitar que
COPY se
agregue al archivo de salida
temp_data.txt
^ Z, que es el carácter de control sustituto
SUB
con el valor de código hexadecimal 1A.
Esta solución es definitivamente mejor que la primera, ya que no importa lo que contenga el archivo
mydata.txt
.
Para comprender los comandos utilizados y cómo funcionan, abra una ventana de símbolo del sistema, ejecute allí los siguientes comandos y lea con cuidado todas las páginas de ayuda que se muestran para cada comando.
-
copy /?
-
echo /?
-
endlocal /?
-
for /?
-
setlocal /?
Tiene un espacio de terminal en la línea
echo %%c>>temp_data.txt
(entre otros) que debe eliminarse.
Esto es típico de la confusión que causan los espacios terminales.