Pregunta

Tengo un archivo bat que debería usar para eliminar una parte de un archivo y guardarlo en otro. Necesito eliminar todos los símbolos entre el texto & Quot; [aaa bbb] & Quot; y " [ccc ddd] " ;. Eso es si tengo el texto:

[aaa bbb]
1
2
3
[ccc ddd]

Debería tener como salida:

[aaa bbb]
[ccc ddd]

Gracias

EDITAR: me gustaría aclarar la pregunta. Debería eliminar todos los símbolos entre marcador1 y marcador2. Marker1 y marker2 son solo algunas palabras o partes del texto, pero no líneas obligatorias. Por ejemplo, tendría:

[aaa bbb] [ccc]
1
2
3
4
5
[www yyy]

Si quiero eliminar el texto entre [aaa bbb] y [www aaa] debería tener como salida:

[aaa bbb] 
[www yyy]
¿Fue útil?

Solución

Eche un vistazo a la sección " Eliminar entre el marcador 1 y el marcador2 " en esta página de sugerencias de sed

Aplicandolo en su ejemplo. clean.sed :

/^\[aaa bbb\]$/,/^\[ccc ddd\]$/{
 /^\[aaa bbb\]$/!{
   /^\[ccc ddd\]$/!d
 }
}

Ejecutar usando:

sed -f clean.sed inputfile.txt

Para editar el archivo de entrada " en su lugar " ;, use la opción -i para sed:

sed -i.bak -f clean.sed datafile.txt

Una copia de seguridad del archivo con el nombre " datafile.txt.bak " se guarda antes de editar el original.

EDITAR: dado que la suposición de que los marcadores siempre estaban en una línea propia era incorrecta, aquí hay un script que puede manejar marcadores en el medio de una línea:

/\[aaa bbb\]/,/\[ccc ddd\]/{
  s/\[aaa bbb\].*/[aaa bbb]/
  s/.*\[ccc ddd\]/[ccc ddd]/
  /\[aaa bbb\]$/!{
    /^\[ccc ddd\]/!d
  }
}

Para esta entrada:

foo[aaa bbb]1
2
3
4
5[ccc ddd]bar
foo
[aaa bbb]
1
2
3
[ccc ddd]
bar

Produce:

foo[aaa bbb]
[ccc ddd]bar
foo
[aaa bbb]
[ccc ddd]
bar

¡Nota! no puede manejar archivos donde los marcadores pueden aparecer en la misma línea.

EDITAR de nuevo: Si el formato de entrada para el marcador 1 es tal que siempre puede contar con que esté en una línea propia, puede simplificar un poco el guión:

/^\[aaa bbb\]$/,/\[ccc ddd\]/{
  s/.*\[ccc ddd\]/[ccc ddd]/
  /^\[aaa bbb\]$/!{
    /^\[ccc ddd\]/!d
  }
}

(Anclar el marcador 1 al principio y al final de una línea y omitir el recorte de la línea del marcador 1).

Otros consejos

Tenga en cuenta que sed está disponible para Windows, junto con un grupo completo de otras utilidades GNU. No estoy seguro si está preguntando si hay un equivalente, o cómo hacerlo realmente una vez que tenga la herramienta.

D:\tmp\sed.exe -f sedscript.sed D:\tmp\test.txt >c:\tmp\test2.txt


/^\[Product Feature\]$/,/^\[Dm$/{
 /^\[Product Feature\]$/!{
 /^\[Dm$/!d 
 }
 } 

Miré cmd y power shell: no encuentro nada útil. Consígase ActivePerl?

Si confía en el script VB " sed-like " de esta respuesta ...

sed.vbs:

Dim pat, patparts, rxp, inp
pat = WScript.Arguments(0)
patparts = Split(pat,"/")
Set rxp = new RegExp
rxp.Global = True
rxp.Multiline = False
rxp.Pattern = patparts(1)
Do While Not WScript.StdIn.AtEndOfStream
  inp = WScript.StdIn.ReadLine()
  WScript.Echo rxp.Replace(inp, patparts(2))
Loop

Puede escribir
cscript /Nologo sed.vbs s/^\d+\s*$/ < in.txt (en.txt es su texto inicial)

y obtendrá el resultado esperado ...

^\d+\s*$

Apuntaría a cualquier línea que comience con uno o más dígitos, seguido de 0 o más espacios dentro de una línea.


Ese no es el mejor " pure sed " solución y en realidad no puede eliminar líneas, pero esta es una " vista-compatible " solución ...


En realidad, el siguiente truco interpreta deliberadamente el " d sed-command " podría 'eliminar' líneas:

Dim pat, patparts, rxp, inp
pat = WScript.Arguments(0)
patparts = Split(pat,"/")
Set rxp = new RegExp
rxp.Global = True
rxp.Multiline = False
rxp.Pattern = patparts(1)
Do While Not WScript.StdIn.AtEndOfStream
  inp = WScript.StdIn.ReadLine()
  out = rxp.Replace(inp, patparts(2))
  if not patparts(2)="d" or not out="d" Then
    WScript.Echo out
  end if
Loop

<=> realmente produciría:

[aaa bbb]
[ccc ddd]

En un .bat, podría tener un sed.bat:

cscript /Nologo sed.vbs %1 < %2

y luego ejecute ese .bat así:

C:\prog\sed>sed.bat s/^\d+\s*$/d in.txt
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top