Archivo por lotes para reemplazar la fila que contiene un valor de cadena específico


0

Tengo un archivo de interfaz, por ejemplo, llamado RawData.txt que contiene diferentes regiones de datos que pueden variar desde unos pocos miles de líneas hasta más de 100,000 líneas de datos.

Hay una mezcla de líneas que contienen por ejemplo

01 00000000000000000000000000000198699 XYZ

que tienen valores int distintos de 0 incluidos que a veces necesitan ser reemplazados por

01 00000000000000000000000000000000000 XYZ

pero debido a la variabilidad del valor int entre los marcadores 01 y XYZ, buscar y reemplazar directamente en un editor de texto no funcionará.

La parte que necesito manipular está estructurada de la siguiente manera:

01  00000000000000000000000000000198699 XYZ

02  157

01  00000000000000000000000000000007749 XYZ

02  158

01  00000000000000000000000000000183279 XYZ

02  163

01  00000000000000000000000000000007749 XYZ

02  165

01  00000000000000000000000000000000000 XYZ

02  175

Idealmente, estoy buscando armar un archivo por lotes que busque cualquier línea en el archivo .txt que comience con el marcador de registro 01 y reemplace la línea con:

01 00000000000000000000000000000000000 XYZ

Supongo que el enfoque más directo es encontrar cualquier línea que comience con el marcador de registro 01 y reemplazar toda la línea, ya que la longitud debe ser idéntica después de que se realicen las modificaciones a los datos existentes.

La mayoría de los ejemplos que he encontrado están relacionados con el reemplazo de una cadena por otra como en el ejemplo aquí

https://stackoverflow.com/questions/23075953/batch-script-to-find-and-replace-a-string-in-text-file-without-creating-an-extra/23076141?utm_medium=organic&utm_source=google_rich_qa&utm_campaign= google_rich_qa

y

https://stackoverflow.com/questions/16614101/batch-script-find-string-in-text-file-by-line-then-replace-whole-line-with-anot?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

pero no puedo modificar para lograr lo que necesito de un archivo por lotes.

Cualquier consejo es apreciado.


Sus ejemplos muestran una mezcla de uno y dos espacios entre 01los 000...campos. ¿Cual es correcta? ¿Puede ocurrir? ¿La cadena de reemplazo requiere el mismo número de espacios?
AFH

1
Oh, te sorprendería lo versátiles que son los editores de texto, porque admiten expresiones regulares. Por lo tanto, en un editor de texto como notepad ++, intente marcar una casilla de verificación de expresiones regulares y haga lo siguiente, [0-9]*y verá que coincidirá con esa cadena de dígitos. Pero un archivo por lotes o cualquier idioma también debería poder hacer lo que quiera.
barlop

Disculpas, los datos de ejemplo tienen un formato deficiente por mi parte. Debe haber 2 espacios entre el 01 y la cadena entera grande y un espacio entre la cadena entera y el marcador XYS.
Grant SDC

@GrantSDC ok, ¿qué tal @for /f "tokens=1,2 delims= " %%f in (a.a) do @IF "%%f"=="01" (echo 01 00000000000000000000000000000000000 XYZ) ELSE IF NOT "%%f"=="01" ECHO %%f %%g
Barlop

1
También probé un ejemplo simple como un archivo con solo la línea abc[multiple spaces]defy trata a abc como el primer token y def como el segundo. Por lo tanto, cuenta ya sea un espacio o una secuencia de espacios contiguos, para ser un delimitador. Vale la pena usar ejemplos simples si quieres entenderlo mejor.
barlop

Respuestas:


1

Esto podría ser lo que quieres

¡Un archivo por lotes se ocupó de esto sorprendentemente bien!

¿Dónde a.aestá tu archivo de datos?

blahblah.bat es un archivo por lotes de una línea

C:\Users\harvey>type blahblah.bat
@for /f "tokens=1,2 delims= " %%f in (a.a) do @IF "%%f"=="01" (echo 01 00000000000000000000000000000000000 XYZ) ELSE IF NOT "%%f"=="01" ECHO %%f %%g

C:\Users\harvey>

ejecutar el archivo por lotes

C:\Users\harvey>blahblah
01 00000000000000000000000000000000000 XYZ
02 157
01 00000000000000000000000000000000000 XYZ
02 158
01 00000000000000000000000000000000000 XYZ
02 163
01 00000000000000000000000000000000000 XYZ
02 165
01 00000000000000000000000000000000000 XYZ
02 175

C:\Users\harvey>

Eso pareció eliminar las líneas en blanco, puede haber una forma de evitarlo con el lote, pero otra forma, además del lote, es usar sed.

C:\Users\harvey>sed -r "s/^01.*/01 00000000000000000000000000000000000 XYZ/" a.a

01 00000000000000000000000000000000000 XYZ

02  157

01 00000000000000000000000000000000000 XYZ

02  158

01 00000000000000000000000000000000000 XYZ

02  163

01 00000000000000000000000000000000000 XYZ

02  165

01 00000000000000000000000000000000000 XYZ

02  175

Por supuesto, podría agregar >b.bpara redirigir esa salida a un nuevo archivo, por lo que podría hacer, sed -r "......." a.a > b.b es decirsed -r "s/^01.*/01 00000000000000000000000000000000000 XYZ/" a.a > b.b


Gracias por este barlop. Tengo un pequeño problema para adaptarme al archivo completo, pero esto me ha dado un buen lugar para comenzar.
Grant SDC

Debo señalar, para la longevidad, vale la pena adaptar estas líneas sed a perl. stackoverflow.com/questions/4794145/perl-one-liner-like-grep ver superuser.com/questions/416419/… Sed puede tener problemas a veces, y Perl es más flexible.
barlop

0

Una forma de analizar el archivo y mantener las líneas vacías es dejar que las líneas se numeren a través de findtr
(para que no estén vacías para el bucle for / f)
y descartar el número después.

:: Q:\Test\2018\05\11\SU_1321271.cmd
@Echo off&SetLocal

Set "ZEROES=00000000000000000000000000000000000"

( for /f "tokens=1,2* delims=: " %%A in (
    'findstr /N "^" RawData.txt'
  ) do If "%%B"=="01" (
      echo=%%B  %ZEROES% XYZ
  ) else (
      echo=%%B  %%C
  )
) >NewData.txt

> type NewData.txt
01 00000000000000000000000000000000000 XYZ

02  157

01 00000000000000000000000000000000000 XYZ

02  158
...
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.