Як мені написати однолінійку sed, щоб додати символ після кожного третього символу?


10

Отже, у мене є рядок, який виглядає приблизно так:

AUGGCCAUGGCGCCCAGAACUGAGAUCAAUAGUACCCGUAUUAACGGGUGA

І я хочу розділити рядок на 3-символьні шматки, розмежовані знаком "+".

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

І я хочу це зробити зі своїм добрим другом sed.

я намагався

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

... без успіху.

Яку sedкоманду можна використовувати?


1
Хіба це не якось пов’язано з Розалінд ? Просто цікаво.
m0nhawk

Відповіді:


16

Оскільки ви не хочете робити трейлінг +, ви можете зробити:

fold -w3 | paste -sd+ -

Тобто, foldрядки на idth 3символів w, і pasteці 3 символьні лінії з ними sельфами, +як dелімінатор, який насправді є як зміна кожного символу нової лінії, але остання в а +. Якщо введення було більше одного рядка, ви закінчите ті рядки, з’єднані з +якими, можливо, можуть бути не такими, які ви хочете.

Якщо вам це потрібно sed, ви можете видалити слід +після:

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

Не хотіли б додати коротке пояснення, як це працює?
NN

@NN Це працює, тому що +$відповідає символу плюс безпосередньо до кінця рядка.
Кріс Даун

fold -w3розбиває рядок на 3 символьні лінії. paste -sd+ -перетворює нові рядки в +.
Багамат

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

щоб ви працювали, вам не потрібно уникати {}символів:

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

1
хто знав! я був так близько, але поки що ... дякую ...
ixtmixilix

Обидва додають кінцевий знак "+". Це призначено?
NN


0

Якщо sed не є обов'язковим, використання Ruby може бути альтернативою. Інтерпретатор Ruby ruby, може використовуватися як sed і awk, запустивши його з -nопцією, яка змушує ітерацію над його входом. Потім інтерпретатора можна подавати однолінійкою Ruby, додавши його в якості аргументу до -eпараметра (який вказує інтерпретатору інтерпретувати аргумент, -eа не шукати сценарій у файлі).

Для цієї конкретної проблеми можна скористатися наступним одноклассником (адаптованим з https://stackoverflow.com/a/3184271/789593 ):

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

Простий мовою це

  • відповідає будь-яким 3 символам або, принаймні, одному символу, scan(/.{3}|.+/)у рядку введення $_(у цьому випадку очікується, що вхід надходить зі стандарту в) і додає кожну відповідність у масив,
  • об'єднує масив у рядок із знаком "+", що з'єднує кожен елемент join("+"),
  • і друкує його, що закінчується новим рядком puts.

Наприклад

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

Зауважте, що він не додає жодних знаків "+".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.