sed in Vista - come eliminare tutti i simboli tra?
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]
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