Bagaimana cara saya menulis satu baris sed untuk menambahkan karakter setelah setiap karakter ketiga?

10

Jadi, saya memiliki string yang terlihat seperti ini:

AUGGCCAUGGCGCCCAGAACUGAGAUCAAUAGUACCCGUAUUAACGGGUGA

Dan saya ingin membagi string menjadi potongan 3-karakter yang dibatasi oleh tanda '+'.

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

Dan saya ingin melakukan itu dengan teman baik saya sed.

Saya mencoba

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

... tanpa hasil.

sedPerintah apa yang bisa saya gunakan?

ixtmixilix
sumber
1
Bukankah ini entah bagaimana terhubung ke Rosalind ? Hanya penasaran.
m0nhawk

Jawaban:

16

Karena Anda tidak ingin trailing +, Anda dapat melakukan:

fold -w3 | paste -sd+ -

Yaitu, foldgaris pada 3karakter width, dan paste3 garis karakter tersebut bersama self dengan +sebagai delimiter yang pada dasarnya seperti mengubah setiap karakter baris baru tetapi yang terakhir menjadi a +. Jika input memiliki lebih dari satu baris, Anda akan berakhir dengan baris-baris yang digabungkan dengan +yang mungkin atau mungkin tidak seperti yang Anda inginkan.

Jika Anda memang menginginkannya sed, Anda dapat menghapus trailing +setelah:

sed 's/.../&+/g;s/+$//'
Stéphane Chazelas
sumber
Maukah Anda menambahkan penjelasan singkat tentang cara kerjanya?
NN
@NN Berhasil karena +$cocok dengan simbol plus tepat sebelum akhir baris.
Chris Down
fold -w3memecah string menjadi 3 garis karakter. paste -sd+ -mengubah baris baru menjadi +.
bahamat
12
sed 's/.../&+/g'

untuk membuat jalan Anda bekerja, Anda tidak perlu melarikan diri {}simbol:

sed -r 's/([A-Z]{3})/\1+/g'
buru-buru
sumber
1
siapa yang tahu! saya sudah sangat dekat namun sejauh ini ... terima kasih ...
ixtmixilix
Keduanya menambahkan trailing '+'. Apakah ini dimaksudkan?
NN
2

Ini mungkin bekerja untuk Anda (sed GNU):

sed 's/...\B/&+/g' file
potong
sumber
0

Jika bukan merupakan keharusan menggunakan Ruby mungkin menjadi alternatif. Penerjemah Ruby ruby,, dapat digunakan seperti sed dan awk dengan menjalankannya dengan -nopsi yang membuatnya mengulangi inputnya. Penerjemah kemudian dapat diberi makan dengan Ruby satu-liner dengan menambahkannya sebagai argumen pada -eopsi (yang memberi tahu penerjemah untuk menafsirkan argumen -edaripada mencari skrip dalam file).

Untuk masalah khusus ini, Anda dapat menggunakan one-liner berikut (diadaptasi dari https://stackoverflow.com/a/3184271/789593 ):

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

Dalam bahasa sederhana itu

  • cocok dengan 3 karakter atau setidaknya satu karakter, scan(/.{3}|.+/)dalam string input, $_(dalam hal ini input diharapkan berasal dari standar) dan menempatkan setiap kecocokan dalam array,
  • bergabung dengan array menjadi string dengan tanda '+' yang menghubungkan setiap elemen join("+"),,
  • dan mencetaknya dihentikan oleh baris baru puts.

Sebagai contoh

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

Perhatikan bahwa itu tidak menambahkan trailing '+'.

NN
sumber