Cómo quitar en archivo de texto, en DOS/CMD, espacios en los extremos de una línea y traer, además, una porción del texto?

Estoy tratando de extraer de un archivo de texto, desde la línea de comandos de Windows, a través de un archivo por lotes, un texto pero que no tenga espacios ni al principio ni al final (algo parecido a la función ESPACIOS() de Excel). Además, y no sé si es posible, extraer una parte de N caracteres a la izquierda o a la derecha de otro texto (similar a lo que hacen las funciones de Excel IZQUIERDA() y DERECHA()). Estuve intentando con FINDSTR pero solo consigo que me traiga la línea completa (con espacios al final).

1 Respuesta

Respuesta
1

No tengo muy claro que vaya a poder conseguir nada pero me gustaría intentarlo. Pero necesito cerrar un poco más las "especificaciones":

1. Serían tres bat, uno (ESPACIOS.BAT) para eliminar los espacios al principio y al final de TODAS las líneas de un archivo (lo cual supondría eliminar totalmente las líneas en blanco si las hubiera), otro (IZQUIERD.BAT) para extraer los N caracteres a la izquierda de un texto en TODAS las líneas en las que los encuentre y un tercero (DERECHA.BAT) para extraer los N caracteres a la derecha de un texto en todas las líneas en las que los encuentre. En todos los casos se respeta el archivo original, pasado como parámetro, y se genera otro con un nombre preestablecido (SALIDA.TXT).

2. Para el primero (ESPACIOS.BAT), habría una limitación en el número de espacios internos (descontados los iniciales y finales), por ejemplo 30, y no es problema sustituir espaciados internos de más de un espacio por un solo espacio.

3. Para el segundo y el tercero se garantiza que en la línea en la que aparezca el texto buscado hay al menos N caracteres a la izquierda (para IZQUIERD.BAT) o a la derecha (para DERECHA.BAT). ¿Se incluirían los espacios internos?

Si estas especificaciones no se ajustan a tus necesidades o no te parecen razonables puedes cambiarlas por las que mejor te parezcan pero creo que hay que "cerrarlas" un poco antes de empezar a buscar una solución.

Hola estimado! Gracias nuevamente! Por casualidad encontré algo interesante con lo cual me evito utilizar las rutinas de reemplazo de caracteres (salvo el de " por #). Lo encontré por accidente en este sitio y está bueno para tenerlo para futuras consultas. Si te fijas trae cierta cantidad de caracteres a partir de la posición que le indiques. https://tooltips.wordpress.com/2008/10/23/generar-ficheros-con-fechahora-desde-un-cmd/

Me alegro de que eso te haya servido, aunque no acabo de hacerme idea de cómo. En cuanto a lo que se dice ahí ya lo conocía y lo he usado a menudo (puedes ver un ejemplo en ¿Como puedo eliminar los caracteres ">" y "<" de un archivo de texto (.txt) con un archivo .BAT? ) Pero es muy de agradecer que nos cuentes lo que encuentras por si le sirve a alguna otra persona.

Dalo por hecho que compartiré todo lo que encuentre! Desde ya, he reducido el código a un 30% pues ya no he necesitado reemplazar caracteres salvo el que mencioné de numeral por comillas. Me falta solo obtener una línea (con el Findstr) que me indica la ubicación y el nombre del archivo DWG pero ese sí me viene con unos molestos espacios y un texto al inicio de la línea el cual deberé eliminar. Les mantengo al tanto de mis avances. Saludos!!

Hola! Bueno, lo de los espacios ya está resuelto porque logré directamente que no se generen. Quedó bastante bien. Ahora resta el desafío final y que es extraer una solo una parte de un string. En éste caso, la parte final a partir de la última barra invertida (la cantidad de barras puede variar). Por ejemplo, para el siguiente texto: "Generado correctamente \\Isilonnas.corp\GIS_FOLDER_UAT\Teco_PAU\Projects\PRUEBA_NO_TOCAR_0_Proyecto.dwg", solo me debe quedar "\\Isilonnas.corp\GIS_FOLDER_UAT\Teco_PAU\Projects\PRUEBA_NO_TOCAR_0_Proyecto.dwg". O sea, debo hacer desaparecer la frase "Generado correctamente ". Sigo investigando por mi lado, si encuentro la forma, la publicaré. Un saludo y buen fin de semana!

Vamos a ver. Si quieres sustituir "Generado correctamente " por nada (es decir, eliminarlo) serviría el bat de partida. Lo pongo aquí con algún ligero retoque:

@echo off
Setlocal EnableDelayedExpansion
del kk_temp.txt
if "%1" == "" goto ayuda
set cadorig=%~2
set cadsust=%~3
for %%f in (%1) do (call :cambiar %%f)
goto fin
:cambiar
set archivo=%1
for /f "tokens=* delims=" %%i in (%archivo%) do (set ANT=%%i
set ANT=!ANT:%cadorig%=%cadsust%!
echo !ANT! >>kk_temp.txt)
rem copy /y kk_temp.txt %archivo%
rem del /q kk_temp.txt
goto :EOF
:Ayuda
Echo Reemplaza una cadena por otra en el contenido de archivos (con comodines)
echo Utiliza un archivo temporal kk_temp.txt que no debe existir previamente
echo Formato: %0 archivos cadorig cadsust
echo Si las cadenas contienen espacios deben escribirse entrecomilladas
echo No funciona si la cadena original contiene un "="
Echo Ejemplo:
echo %0 *.txt de DE
:Fin

Para hacer unas pruebas he generado un archivo (JF.TXT) con líneas que, más o menos, se ajustan a lo que dices:

Generado correctamente \\Isilonnas.corp\GIS_FOLDER_UAT\Teco_PAU\Projects\PRUEBA_NO_TOCAR_0_Proyecto.dwg
\\Isilonnas.corp\GIS_FOLDER_UAT\Teco_PAU\_NO_TOCAR_0_Proyecto.dwg
Generado correctamente \\Isilonnas.ggg\GIS_FOLDER_UAT\Projects\PRUEBA_NO_TOCAR_1_Proyecto.dwg
Generado correctamente \\Isil.ggg\PRUEBA_NO_TOCAR_1_Proyecto.dwg
 \\Isilonnas.corp\GIS_FOLDER\Teco_PAU\_NO_TOCAR_0_Proyecto.dwg

Te copio a continuación un ejemplo que demuestra, creo, el correcto funcionamiento del JF2.BAT (que es como le he llamado al BAT anterior):

D:\BAT>jf2 jf.txt "Generado correctamente " ""
D:\BAT>type kk_temp.txt
\\Isilonnas.corp\GIS_FOLDER_UAT\Teco_PAU\Projects\PRUEBA_NO_TOCAR_0_Proyecto.dwg
\\Isilonnas.corp\GIS_FOLDER_UAT\Teco_PAU\_NO_TOCAR_0_Proyecto.dwg
\\Isilonnas.ggg\GIS_FOLDER_UAT\Projects\PRUEBA_NO_TOCAR_1_Proyecto.dwg
\\Isil.ggg\PRUEBA_NO_TOCAR_1_Proyecto.dwg
 \\Isilonnas.corp\GIS_FOLDER\Teco_PAU\_NO_TOCAR_0_Proyecto.dwg

Como puedes ver el kk_temp.txt tiene el texto resultante de hacer la sustitución elegida.

¡Gracias! 

Hemos llegado al mismo resultado veo! :)

Explico como funciona básicamente todo mi trabajo:

Desde Autocad, a través de unas instrucciones de Autolisp genero un archivo NO_BORRAR_1.TXT cuyo contenido es el siguiente y que sus líneas varían conforme la PC activa, el proyecto y el usuario que esté logueado. Para este caso y a modo de ejemplo sería algo así:
SET NOMBRE_ID=5468
copy \\Isilonnas.corp\GIS_FOLDER_UAT\Telecom_PAU\Projects\5468*.XML "%LOCALAPPDATA%\Dsoft\SIPRE\Backup\%nombre_id%_%zname%.xml"
copy "C:\Users\u579432\appdata\local\autodesk\autocad map 3d 2012\r18.2\esp\Dibujo1_1_1_1659.log" %LOCALAPPDATA%\Dsoft\SIPRE\Backup\"*_%zname%.log"
findstr /b "Generado correctamente \\Isilonnas" "C:\Users\u579432\appdata\local\autodesk\autocad map 3d 2012\r18.2\esp\Dibujo1_1_1_1659.log">"C:\4DataLink\Enviar_Logs\00.txt"
Este archivo forma parte, junto con otro que se llama NO_BORRAR_2.TXT donde tengo cargadas unas líneas de comandos del 7Zip para comprimir todos los archivos que colecciono para enviarlos por correo a un proveedor.

NO_BORRAR_2.TXT

"C:\Program Files\7-Zip\"7zG.exe a "%computername%_%username%_%zname%.7z" %LOCALAPPDATA%\Dsoft\SIPRE\Backup\"*.dwg"
"C:\Program Files\7-Zip\"7zG.exe u -seml. "%computername%_%username%_%zname%.7z" %LOCALAPPDATA%\Dsoft\SIPRE\Backup\"*%zname%.*"
del *.7z

También genero un tercer archivo TXT llamado 00.TXT donde guardo una línea que busco con Findstr en un log de Autocad.

El .CMD principal al cual denominé "Recupera_Logs.cmd" es el que disparo y me genera un segundo archivo por lotes llamado "zipear_logs.cmd" el cual es resultado de la concatenación de NO_BORRAR_1.TXT+NO_BORRAR2.TXT+00.TXT pero, éste último lo reproceso previamente, precisamente utilizando la rutina de reemplazo de caracteres que ya habíamos visto. O sea:

for /f "tokens=* delims=" %%i in (00.txt) do (set ANT=%%i&set ANT=!ANT:Generado correctamente \\=copy "\\!
echo !ANT! >> kk_temp.txt)
type kk_temp.txt>C:\4DataLink\Enviar_Logs\00.txt
del kk_temp.txt

for /f "tokens=* delims=" %%i in (00.txt) do (set ANT=%%i&set ANT=!ANT:Proyecto.dwg=Proyecto.dwg" "%LOCALAPPDATA%\Dsoft\SIPRE\Backup\"!
echo !ANT! >> kk_temp.txt)
type kk_temp.txt>C:\4DataLink\Enviar_Logs\00.txt
del kk_temp.txt

Aquí coloco el script principal RECUPERA_LOGS (al final se ve el proceso donde trabajo el script):


=============================================

RECUPERA_LOGS.CMD

@echo off
Setlocal EnableDelayedExpansion

if exist zipear_logs.cmd del zipear_logs.cmd
pause
Set zname=%Date:~6,4%%Date:~3,2%%Date:~0,2%_%Time:~0,2%%Time:~3,2%%Time:~6,2%>zipear_logs.cmd
set archivo=nombre.txt

:Inicia
Echo Set zname=%zname%>zipear_logs.cmd
Echo del %LOCALAPPDATA%\Dsoft\SIPRE\Backup\*.* /q
Echo copy C:\4DataLink\EM-PM\pm_client_gis.log %LOCALAPPDATA%\Dsoft\SIPRE\Backup\"pm_client_gis_%zname%.log">>zipear_logs.cmd
Echo copy C:\4DataLink\EM-PM\log\pm_client.log %LOCALAPPDATA%\Dsoft\SIPRE\Backup\"pm_client_%zname%.log">>zipear_logs.cmd
Echo copy %LOCALAPPDATA%\Dsoft\SIPRE\Sipre.log %LOCALAPPDATA%\Dsoft\SIPRE\Backup\"SIPRE_%zname%.log">>zipear_logs.cmd
Echo copy %LOCALAPPDATA%\Dsoft\SIPRE\SipreErrors.log %LOCALAPPDATA%\Dsoft\SIPRE\Backup\"SIPREERRORS_%zname%.log">>zipear_logs.cmd


:INICIA4
:cambia_#_por_comillas

set archivo=NO_BORRAR_1.txt

for /f "tokens=* delims=" %%i in (NO_BORRAR_1.txt) do (set ANT=%%i&set ANT=!ANT:#="!
echo !ANT! >> kk_temp.txt)
type kk_temp.txt

type kk_temp.txt>NO_BORRAR_1.txt
del kk_temp.txt

Type NO_BORRAR_1.txt>>C:\4DataLink\Enviar_Logs\zipear_logs.cmd

for /f "tokens=* delims=" %%i in (00.txt) do (set ANT=%%i&set ANT=!ANT:Generado correctamente \\=copy "\\!
echo !ANT! >> kk_temp.txt)
type kk_temp.txt>C:\4DataLink\Enviar_Logs\00.txt
del kk_temp.txt

for /f "tokens=* delims=" %%i in (00.txt) do (set ANT=%%i&set ANT=!ANT:Proyecto.dwg=Proyecto.dwg" "%LOCALAPPDATA%\Dsoft\SIPRE\Backup\"!
echo !ANT! >> kk_temp.txt)
type kk_temp.txt>C:\4DataLink\Enviar_Logs\00.txt
del kk_temp.txt

type C:\4DataLink\Enviar_Logs\00.txt>>C:\4DataLink\Enviar_Logs\zipear_logs.cmd

Type NO_BORRAR_2.txt>>C:\4DataLink\Enviar_Logs\zipear_logs.cmd
REM start zipear_logs.cmd (lo inicio desde AUTOLISP)

==============================================

Se genera "zipear_logs.cmd"

Set zname=20161202_185707
copy C:\4DataLink\EM-PM\pm_client_gis.log C:\Users\u579432\AppData\Local\Dsoft\SIPRE\Backup\"pm_client_gis_20161202_185707.log"
copy C:\4DataLink\EM-PM\log\pm_client.log C:\Users\u579432\AppData\Local\Dsoft\SIPRE\Backup\"pm_client_20161202_185707.log"
copy C:\Users\u579432\AppData\Local\Dsoft\SIPRE\Sipre.log C:\Users\u579432\AppData\Local\Dsoft\SIPRE\Backup\"SIPRE_20161202_185707.log"
copy C:\Users\u579432\AppData\Local\Dsoft\SIPRE\SipreErrors.log C:\Users\u579432\AppData\Local\Dsoft\SIPRE\Backup\"SIPREERRORS_20161202_185707.log"
SET NOMBRE_ID=5468
copy \\Isilonnas.corp\GIS_FOLDER_UAT\Telecom_PAU\Projects\5468*.XML "%LOCALAPPDATA%\Dsoft\SIPRE\Backup\%nombre_id%_%zname%.xml"
copy "C:\Users\u579432\appdata\local\autodesk\autocad map 3d 2012\r18.2\esp\Dibujo1_1_1_1659.log" %LOCALAPPDATA%\Dsoft\SIPRE\Backup\"*_%zname%.log"
findstr /b "Generado correctamente \\Isilonnas" "C:\Users\u579432\appdata\local\autodesk\autocad map 3d 2012\r18.2\esp\Dibujo1_1_1_1659.log">"C:\4DataLink\Enviar_Logs\00.txt"
copy "\\Isilonnas.corp\GIS_FOLDER_UAT\Telecom_PAU\Projects\PRUEBA_NO_TOCAR_0_Proyecto.dwg" "C:\Users\u579432\AppData\Local\Dsoft\SIPRE\Backup\"
"C:\Program Files\7-Zip\"7zG.exe a "%computername%_%username%_%zname%.7z" %LOCALAPPDATA%\Dsoft\SIPRE\Backup\"*.dwg"
"C:\Program Files\7-Zip\"7zG.exe u -seml. "%computername%_%username%_%zname%.7z" %LOCALAPPDATA%\Dsoft\SIPRE\Backup\"*%zname%.*"
del *.7z

====================================================

Espero no haber generado mayor confusión con tanto código. Saludos!!

Perfecto. Solo quiero añadir que el código que inluía para el JF2.BAT también funciona para sustituir el carácter # por el carácter " con la sintaxis:

jf2 jf.txt # """

(Tres veces las dobles comillas). Sin embargo en una sustitución al revés (" por #, por ejemplo) no funcionaría (habría que cambiar el orden de los campos en el propio código)

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas