2012-06-25 4 views
5

Parte del mio 4 uscite colonna di simile a questo:trovare il numero, e rimuovere caratteri adiacenti pari a questo numero

5 cc1kcc1kc 5 cc1kcc1kc 
5 cc2ppggg 5 cc2ppggg 
6 ccg12qqqqqqqqqqqqggg 10 ccccg11qqqqqqqqqqqggggg 
3 4qqqqcgc1q 12 cgccgccgccgc 

Voglio solo la seconda e quarta colonna cambiati, c'è un modo con awk/sed di rimuovere i numeri con i caratteri accanto a loro? Oppure sarebbe più facile/migliore usare uno script perl per eseguire questa trasformazione?

L'output risultante dovrebbe essere simile a questo:

5 ccccc 5 ccccc 
5 ccggg 5 ccggg 
6 ccgggg 10 ccccgggggg 
3 cgc 12 cgccgccgccgc 

risposta

4

Prendendo la domanda alla lettera, questo rimuove i prossimi n personaggi dai campi 2 e 4 per qualsiasi n incorporato nel campo.

perl -lane 'for $i (1, 3) {@nums = $F[$i] =~ /(\d+)/g; for $num (@nums) {$F[$i] =~ s/$num.{$num}//}}; print join("\t", @F)' 

Le altre risposte rimuovono il numero e tutti i caratteri che seguono che sono gli stessi.

Per illustrare la differenza tra la mia risposta e gli altri, utilizzare il seguente entrata:

6 ccg8qqqqqqqqqqqqggg 10 ccccg3qqqqqqqqqqqggggg 

mie uscite versione questo:

6 ccgqqqqggg  10  ccccgqqqqqqqqggggg 

mentre la produzione loro questo:

6 ccgggg 10 ccccgggggg 
3

Con perl:

perl -pe 's/\d+([^\d\s])\1*//g' 
+0

+1 perché questo ha fatto il lavoro, ma una piccola spiegazione sarebbe stata buona. – simbabque

+0

Ok. L'opzione '-p' fa sì che Perl assuma il seguente ciclo attorno al codice (opzione' -e' e one-liner), che lo rende iterato su argomenti alquanto simili a 'sed'. E la descrizione di regexp si trova in [risposta a 'sed'] (http://stackoverflow.com/a/11186538/1186729). –

+2

Questo rimuove i "10" e "12" che sono nella colonna 3 nelle righe 3 e 4. –

2

con sed:

sed 's/[0-9]\+\([a-z]\)\1*//g' 

Il match trova qualsiasi stringa di cifre ([0-9]+) seguito da qualsiasi lettera ([a-z]). \1* corrisponde a qualsiasi occorrenza successiva di quel carattere. Il modificatore /g (globale) si assicura che la sostituzione venga eseguita più di una volta per riga.

1

Questo potrebbe funzionare per voi (GNU sed):

sed 'h;s/\S*\s*\(\S*\).*/\1/;:a;s/[^0-9]*\([0-9]\+\).*/sed "s|\1.\\{\1\\}||" <<<"&"/e;ta;H;g;/\n.*\n/bb;s/\(\S*\s*\)\{3\}\(\S*\).*/\2/;ba;:b;s/^\(\S*\s*\)\(\S*\)\([^\n]*\)\n\(\S*\)/\1\4\3/;s/\(\S*\s*\)\n\(.*\)/\2/' file