LINUX.ORG.RU

Как объединить замену и транслитерацию?

 , ,


0

1

Как в sed (или vim) объединить в одну операцию выделение фрагмента строки и замену символа в этом фрагменте? Или как провести замену не в строке, а в подстроке, когда неизвестно, сколько замен произвести и сколько пропустить?

Есть набор URL-ов вида:

http://drabadan.ord/drabadan-1/cover/  
http://drabadan.ord/drabadan-1/pg1-1/  
http://drabadan.ord/drabadan-1/pg1-4/2/  
http://drabadan.ord/drabadan-again/pg5-1/  
http://drabadan.ord/list/  

Нужно преобразовать его в скрипт вида:

curl -LR http://drabadan.ord/drabadan-1/cover/ -o drabadan-1.cover.htm
curl -LR http://drabadan.ord/drabadan-1/pg1-1/ -o drabadan-1.pg1-1.htm
curl -LR http://drabadan.ord/drabadan-1/pg1-4/2/ -o drabadan-1.pg1-4.2.htm
curl -LR http://drabadan.ord/drabadan-again/pg5-1/ -o drabadan-again.pg5-1.htm
curl -LR http://drabadan.ord/list/ -o list.htm

То есть повторить исходную строку, затем вывести её же без «http://drabadan.ord/» и с заменой всех оставшихся «/» на «.» (заранее неизвестное число раз).

В итоге я всё сделал через регулярные выражения на Питоне. Можно через paste. Но можно ли тут обойтись однострочником на sed?

★★★★★
Ответ на: комментарий от Bfgeshka

запиши исходную строку в переменную сперва и преобразуй её выхлоп.

То есть только так?

LINE=http://... ; echo curl -LR $LINE -o `echo $LINE | sed 's|https://dobro.ord/||; s|/|.|g'`htm

Присваивать переменные внутри скриптов sed не умеет? Мне казалось, что умеет, но я этого нигде не могу найти.

question4 ★★★★★
() автор топика
Ответ на: комментарий от iron

:%s#\v^\s*(http://drabadan\.ord/)?(.{-})/?\s*$#\=trim(submatch(0)).' '.substitute(trim(submatch(2)), '/', '.', 'g').'.htm'#

Не сразу понял, куда добавить остальные параметры. Полный ответ:

:%s#\v^\s*(http://drabadan\.ord/)?(.{-})/?\s*$#\='curl -LR --no-clobber '.trim(submatch(0)).' -o '.substitute(trim(submatch(2)), '/', '.', 'g').'.htm'#

Спасибо.

question4 ★★★★★
() автор топика
Последнее исправление: question4 (всего исправлений: 1)
Ответ на: комментарий от question4

Вместо substitute можно использовать tr():

:%s#\v^\s*(http://drabadan\.ord/)?(.{-})/?\s*$#\=$'curl -LR --no-clobber {trim(submatch(0))} -o {tr(trim(submatch(2)), '/', '.')}.htm'#

по идее от trim() можно избавиться – если и будут пробелы то curl это не помешает:

:%s#\v^\s*(http://drabadan\.ord/)?(.{-})/?\s*$#\=$'curl -LR --no-clobber {submatch(0)} -o {tr(submatch(2), '/', '.')}.htm'#

PS, использовал string interpolation $'bla bla {vimscript} bla bla'

habamax ★★★
()
Последнее исправление: habamax (всего исправлений: 3)
sed 's|\s\+$||;h;s|^http://drabadan.ord/||;s@/\+$@@;s|/|.|g;s|$|.htm|;s|^|-o |;H;g;y|\n| |;s|^|curl -LR |'
i-rinat ★★★★★
()
Ответ на: комментарий от question4

Присваивать переменные внутри скриптов sed не умеет?

Переменных в явном виде нет, но помимо рабочего пространства есть ещё загашник, и есть операции, которые позволяют работать с этим загашником. Похоже на переменную, но только «переменная» одна, причём ещё и с ограниченной функциональностью.

i-rinat ★★★★★
()

Я бы так сделал:

awk '{
	o = $1
	sub(/^http:..drabadan.ord./, "", o)
	gsub(/\//, ".", o)
	print "curl -LR", $1, "-o", o "htm"
}'

Но вообще правильно было бы использовать trurl 1.

kaldeon ★★
()
Последнее исправление: kaldeon (всего исправлений: 1)
Ответ на: комментарий от i-rinat

загашник, и есть операции, которые позволяют работать с этим загашником. Похоже на переменную, но только «переменная» одна, причём ещё и с ограниченной функциональностью.

Речь про «hold space»? Только сейчас название вспомнил. Или есть что-то ещё?

question4 ★★★★★
() автор топика
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария