Domanda

Ho un file bat che dovrei usare per cancellare una parte di un file e salvarlo in un altro. Devo eliminare tutti i simboli tra il testo & Quot; [aaa bbb] & Quot; e " [ccc ddd] " ;. Cioè se ho il testo:

[aaa bbb]
1
2
3
[ccc ddd]

Dovrei avere come output:

[aaa bbb]
[ccc ddd]

Grazie

MODIFICA: Vorrei chiarire la domanda. Dovrei eliminare tutti i simboli tra marker1 e marker2. Marker1 e marker2 sono solo alcune parole o parti di testo ma non linee obbligatorie. Ad esempio avrei:

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

Se voglio cancellare il testo tra [aaa bbb] e [www yyy] dovrei avere come output:

[aaa bbb] 
[www yyy]
È stato utile?

Soluzione

Dai un'occhiata alla sezione " Elimina tra marker 1 e marker2 " su questa pagina di suggerimenti su sed

Applicandolo sul tuo esempio. clean.sed :

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

Esegui utilizzando:

sed -f clean.sed inputfile.txt

Per modificare il file di input " in posizione " ;, usa l'opzione -i per sed:

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

Una copia di backup del file con il nome " datafile.txt.bak " viene salvato prima di modificare l'originale.

EDIT: dato che l'ipotesi che i marcatori fossero sempre su una linea propria era sbagliata, ecco uno script che può gestire i marcatori nel mezzo di una linea:

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

Per questo input:

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! Non è impossibile gestire i file in cui gli indicatori possono apparire sulla stessa riga.

MODIFICA di nuovo: Se il formato di input per il marker 1 è tale che puoi sempre contare sul fatto che si trova su una linea a sé stante, puoi semplificare un po 'lo script:

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

(Ancoraggio del marcatore 1 all'inizio e alla fine di una linea e saltando il taglio della linea del marcatore 1)

Altri suggerimenti

Nota che sed è disponibile per Windows, insieme a un intero gruppo di altre utility GNU. Non sono sicuro se stai chiedendo se esiste un equivalente, o come farlo effettivamente una volta che hai lo strumento.

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


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

Ho guardato cmd e power shell - non trovo nulla di utile. Ottieni ActivePerl?

Se ti fidi dello script VB " sed-like " di questa risposta ...

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

Puoi digitare
cscript /Nologo sed.vbs s/^\d+\s*$/ < in.txt (in.txt è il tuo testo iniziale)

e otterrai l'output previsto ...

^\d+\s*$

Indirizzerebbe qualsiasi riga che inizia con una o più cifre, seguita da 0 o più spazi all'interno di una riga.


Questo non è il migliore " pure sed " soluzione e non può effettivamente eliminare le righe, ma questa è una " nativa; <<>> quot; soluzione ...


In realtà, il seguente hack interpreta deliberatamente il " d sed-command " potrebbe essere in grado di "eliminare" le righe:

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

<=> produrrebbe effettivamente:

[aaa bbb]
[ccc ddd]

In un .bat, potresti avere un sed.bat:

cscript /Nologo sed.vbs %1 < %2

e quindi esegui quel .bat in questo modo:

C:\prog\sed>sed.bat s/^\d+\s*$/d in.txt
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top