Wie schreibe ich einen sed Einzeiler, um nach jedem dritten Zeichen ein Zeichen hinzuzufügen?

10

Ich habe also eine Zeichenfolge, die so aussieht:

AUGGCCAUGGCGCCCAGAACUGAGAUCAAUAGUACCCGUAUUAACGGGUGA

Und ich möchte die Zeichenfolge in 3-stellige Abschnitte aufteilen, die durch ein '+' - Zeichen getrennt sind.

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

Und das möchte ich mit meinem guten Freund machen sed.

Ich habe es versucht

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

... ohne Erfolg.

Welchen sedBefehl kann ich verwenden?

ixtmixilix
quelle
1
Ist das nicht irgendwie mit Rosalind verbunden ? Nur neugierig.
m0nhawk

Antworten:

16

Da Sie kein Trailing möchten +, können Sie Folgendes tun:

fold -w3 | paste -sd+ -

Das heißt, folddie Zeilen auf der 3Zeichen- wID und pastedie 3 Zeichenzeilen mit ihnen swerden +als dElimiter verwendet, was praktisch so ist, als würde jedes neue Zeilenzeichen außer dem letzten in ein geändert +. Wenn die Eingabe mehr als eine Zeile hatte, werden die Zeilen mit einer Zeile verbunden, +die möglicherweise Ihren Wünschen entspricht oder nicht.

Wenn Sie es brauchen sed, können Sie das Trailing +nach entfernen :

sed 's/.../&+/g;s/+$//'
Stéphane Chazelas
quelle
Würde es Ihnen etwas ausmachen, eine kurze Erklärung hinzuzufügen, wie das funktioniert?
NN
@NN Es funktioniert, weil +$ein Pluszeichen unmittelbar vor dem Ende einer Zeile übereinstimmt.
Chris Down
fold -w3Bricht die Zeichenfolge in 3 Zeichenzeilen. paste -sd+ -verwandelt die Zeilenumbrüche in +.
Bahamat
12
sed 's/.../&+/g'

Um sich an die Arbeit zu machen, müssen Sie den {}Symbolen nicht entkommen :

sed -r 's/([A-Z]{3})/\1+/g'
eilen
quelle
1
Wer wusste! Ich war so nah und doch so weit ... danke ...
ixtmixilix
Beide fügen ein abschließendes '+' hinzu. Ist das beabsichtigt?
NN
2

Dies könnte für Sie funktionieren (GNU sed):

sed 's/...\B/&+/g' file
Potong
quelle
0

Wenn sed kein Muss ist, kann die Verwendung von Ruby eine Alternative sein. Der Ruby-Interpreter rubykann wie sed und awk verwendet werden, indem er mit der -nOption ausgeführt wird, mit der er über seine Eingabe iteriert. Der Interpreter kann dann mit einem Ruby-Einzeiler gespeist werden, indem er der -eOption als Argument hinzugefügt wird (wodurch der Interpreter angewiesen wird, das Argument zu interpretieren, -eanstatt in einer Datei nach einem Skript zu suchen).

Für dieses spezielle Problem können Sie den folgenden Einzeiler verwenden (angepasst von /programming//a/3184271/789593 ):

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

Im Klartext ist es

  • Entspricht 3 beliebigen Zeichen oder mindestens einem Zeichen scan(/.{3}|.+/)in der Eingabezeichenfolge $_(in diesem Fall wird erwartet, dass die Eingabe vom Standard-In stammt) und fügt jede Übereinstimmung in ein Array ein.
  • schließt sich das Array in einen String mit einem jeweiligen Element ‚+‘ verbindet, join("+"),
  • und druckt es mit einem Zeilenumbruch abgeschlossen puts.

Beispielsweise

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

Beachten Sie, dass kein abschließendes '+' hinzugefügt wird.

NN
quelle