Jak napisać linijkę sed, aby dodać znak po co trzecim znaku?

10

Mam więc ciąg, który wygląda tak:

AUGGCCAUGGCGCCCAGAACUGAGAUCAAUAGUACCCGUAUUAACGGGUGA

Chcę podzielić ciąg na 3-znakowe fragmenty rozdzielone znakiem „+”.

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

I chcę to zrobić z moim dobrym przyjacielem sed.

próbowałem

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

... bez powodzenia.

Jakiego sedpolecenia mogę użyć?

ixtmixilix
źródło
1
Czy to nie jest w jakiś sposób powiązane z Rosalind ? Po prostu ciekawy.
m0nhawk

Odpowiedzi:

16

Ponieważ nie chcesz końcowego +, możesz:

fold -w3 | paste -sd+ -

Oznacza to, foldże linie na idth 3postaci wi pastete 3 linie znaków wraz z nimi selfami +jako delimiterem, co w rzeczywistości przypomina zmianę każdego znaku nowej linii oprócz ostatniej na znak +. Jeśli dane wejściowe miały więcej niż jedną linię, skończysz z tymi liniami połączonymi z, +które mogą, ale nie muszą być tym, czego chcesz.

Jeśli potrzebujesz sed, możesz usunąć końcowe +po:

sed 's/.../&+/g;s/+$//'
Stéphane Chazelas
źródło
Czy mógłbyś dodać krótkie wyjaśnienie, jak to działa?
NN,
@NN Działa, ponieważ +$dopasowuje symbol plus bezpośrednio przed końcem linii.
Chris Down
fold -w3dzieli ciąg na 3 linie znaków. paste -sd+ -zamienia nowe linie w +.
bahamat
12
sed 's/.../&+/g'

aby zacząć działać, nie musisz uciekać od {}symboli:

sed -r 's/([A-Z]{3})/\1+/g'
wysypka
źródło
1
kto wiedział! byłem tak blisko, ale jak dotąd ... dzięki ...
ixtmixilix
Oba dodają końcowe „+”. Czy to jest zamierzone?
NN,
2

To może Ci pomóc (GNU sed):

sed 's/...\B/&+/g' file
potong
źródło
0

Jeśli sed nie jest koniecznością, użycie Ruby może być alternatywą. Interpretator Ruby ruby, może być używany jak sed i awk, uruchamiając go z -nopcją, która powoduje iterację po wprowadzonych danych. Tłumacz może być następnie zasilany jednowierszowym Ruby, dodając go jako argument do -eopcji (która mówi tłumaczowi, aby zinterpretował argument-e zamiast szukać skryptu w pliku).

W przypadku tego konkretnego problemu można użyć następującego linka (dostosowanego z https://stackoverflow.com/a/3184271/789593 ):

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

W prostym języku to

  • dopasowuje dowolne 3 znaki lub co najmniej jeden znak scan(/.{3}|.+/)w ciągu wejściowym,$_ (w tym przypadku oczekuje się, że dane wejściowe będą pochodzić ze standardowego wejścia) i umieszcza każde dopasowanie w tablicy,
  • łączy tablicę w ciąg znaków z „+” łączącym każdy element, join("+") ,
  • i drukuje to zakończone nową linią puts.

Na przykład

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

Zauważ, że nie dodaje końcowego „+”.

NN
źródło