2013-05-30 4 views
5

Ho un file che contiene le linee comeSostituire/cancellare i caratteri speciali all'interno di stringhe corrispondenti a sed

I want a lot <*tag 1> more <*tag 2>*cheese *cakes. 

Sto cercando di rimuovere il * entro <>, ma non al di fuori. I tag possono essere più complicati di quelli precedenti. Ad esempio, <*better *tag 1>.

Ho provato /\bregex\b/s/\*//g, che funziona per il tag 1 ma non per il tag 2. Quindi, come posso farlo funzionare anche per il tag 2?

Molte grazie.

+0

si può avere nidificato '<>'? –

+0

Nel mio caso, non ci sarà nidificazione <>. Saluti. – ToonZ

risposta

3

Obbligatorio soluzione Perl:

perl -pe '$_ = join "", 
     map +($i++ % 2 == 0 ? $_ : s/\*//gr), 
     split /(<[^>]+>)/, $_;' FILE 

Aggiungi:

+0

+1 per la fodera 's /// e' –

+0

Great perl one-liner. +1 anche da parte mia – ToonZ

3

soluzione semplice se si dispone di un solo asterisco nel tag

sed 's/<\([^>]*\)\*\([^>]*\)>/<\1\2>/g' 

Se si può avere di più, è possibile utilizzare sed goto sistema di etichettatura

sed ':doagain s/<\([^>]*\)\*\([^>]*\)>/<\1\2>/g; t doagain' 

Dove doagain è l'etichetta per il ciclo, t doagain è un salto condizionale all'etichetta doagain. Fare riferimento al manuale sed:

t label 

Branch to label only if there has been a successful substitution since the last 
input line was read or conditional branch was taken. The label may be omitted, in 
which case the next cycle is started. 
+0

Grazie per la soluzione loop. :-) – ToonZ

+0

Hai chiesto una soluzione sed :) Sono contento che ti abbia aiutato;) – bartimar

1

awk potrebbe risolvere il problema:

awk '{x=split($0,a,/<[^>]*>/,s);for(i in s)gsub(/\*/,"",s[i]);for(j=1;j<=x;j++)r=r a[j] s[j]; print r}' file 

versione più leggibile:

awk '{x=split($0,a,/<[^>]*>/,s) 
     for(i in s)gsub(/\*/,"",s[i]) 
     for(j=1;j<=x;j++)r=r a[j] s[j] 
     print r}' file 

test con i tuoi dati:

kent$ cat file 
I want a lot <*tag 1> more <*tag 2>*cheese *cakes. <*better *tag X*> 

kent$ awk '{x=split($0,a,/<[^>]*>/,s);for(i in s)gsub(/\*/,"",s[i]);for(j=1;j<=x;j++)r=r a[j] s[j]; print r}' file 
I want a lot <tag 1> more <tag 2>*cheese *cakes. <better tag X> 
+0

Non ho familiarità con la versione a 4 argomenti di 'split', qual è il quarto argomento? – Lorkenpeist