Come posso scrivere un sed one-liner per aggiungere un personaggio dopo ogni terzo personaggio?


10

Quindi, ho una stringa che assomiglia a questa:

AUGGCCAUGGCGCCCAGAACUGAGAUCAAUAGUACCCGUAUUAACGGGUGA

E voglio dividere la stringa in blocchi di 3 caratteri delimitati da un segno '+'.

AUG+GCC+AUG+GCG+CCC+AGA+ACU+GAG+AUC+AAU+AGU+ACC+CGU+AUU+AAC+GGG+UGA

E voglio farlo con il mio buon amico sed.

Provai

cat codons | sed -r 's/([A-Z]\{3\})/\1\+/g'

... senza successo.

Quale sedcomando posso usare?


1
Non è in qualche modo collegato a Rosalind ? Solo curioso.
m0nhawk,

Risposte:


16

Dal momento che non vuoi un finale +, puoi fare:

fold -w3 | paste -sd+ -

Cioè, foldle linee sull'identità del 3personaggio w, e pastequelle 3 linee di caratteri con loro selfi +come delimiter, che in effetti è come cambiare ogni personaggio della nuova linea, tranne l'ultimo in a +. Se l'input aveva più di una riga, finirai con quelle righe unite con una +che può essere o meno quella che desideri.

Se ne hai bisogno sed, puoi rimuovere il trascinamento +dopo:

sed 's/.../&+/g;s/+$//'

Ti dispiacerebbe aggiungere una breve spiegazione di come funziona?
NN,

@NN Funziona perché +$corrisponde a un simbolo più immediatamente prima della fine di una riga.
Chris Down,

fold -w3spezza la stringa in 3 righe di caratteri. paste -sd+ -trasforma le newline in +.
Bahamat,

12
sed 's/.../&+/g'

per farti lavorare non è necessario sfuggire ai {}simboli:

sed -r 's/([A-Z]{3})/\1+/g'

1
chi lo sapeva! ero così vicino eppure così lontano ... grazie ...
ixtmixilix il

Entrambi aggiungono un '+' finale. Questo è previsto?
NN,

2

Questo potrebbe funzionare per te (GNU sed):

sed 's/...\B/&+/g' file

0

Se sed non è un must usare Ruby potrebbe essere un'alternativa. L'interprete Ruby ruby, può essere usato come sed e awk eseguendolo con l' -nopzione che lo fa scorrere sul suo input. L'interprete può quindi essere alimentato con un one-liner di Ruby aggiungendolo come argomento -eall'opzione (che dice all'interprete di interpretare l'argomento -epiuttosto che cercare uno script in un file).

Per questo particolare problema è possibile utilizzare il seguente one-liner (adattato da https://stackoverflow.com/a/3184271/789593 ):

ruby -ne 'puts $_.scan(/.{3}|.+/).join("+")'

In parole povere

  • corrisponde a 3 caratteri o almeno a un carattere, scan(/.{3}|.+/)nella stringa di input $_(in questo caso si prevede che l'input provenga dallo standard in) e inserisce ogni corrispondenza in un array,
  • unisce l'array in una stringa con un '+' che collega ogni elemento, join("+"),
  • e lo stampa terminato da una nuova riga puts.

Per esempio

echo "AUGGCCAUGGCGCCCAGAACUGAGAUCAAUAGUACCCGUAUUAACGGGUG" | ruby -ne 'puts $_.scan(/.{3}|.+/).join("+")'
AUG+GCC+AUG+GCG+CCC+AGA+ACU+GAG+AUC+AAU+AGU+ACC+CGU+AUU+AAC+GGG+UG

Nota che non aggiunge alcun '+' finale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.