Когда дело доходит до циклических конструкций в sed
, я люблю использовать переводы строк в качестве маркеров для мест, которые мне еще предстоит обработать.Это делает сопоставление намного проще, и я знаю, что они не во вводе, потому что мой ввод - это текстовая строка.
Например:
$ echo A-1,2,3,4,5 | sed 's/,/\n/g;:a s/^\([^0-9]*\)\([^\n]*\)\n/\1\2,\1/; ta'
A-1,A-2,A-3,A-4,A-5
Это работает следующим образом:
s/,/\n/g # replace all commas with newlines (insert markers)
:a # label for looping
s/^\([^0-9]*\)\([^\n]*\)\n/\1\2,\1/ # replace the next marker with a comma followed
# by the prefix
ta # loop unless there's nothing more to do.
Подход похож на @ potong's, но я нахожу регулярное выражение гораздо более читабельным - \([^0-9]*\)
захватывает префикс, \([^\n]*\)
захватывает все до следующего маркера (то есть все, что уже было обработано),и тогда нужно просто собрать его в замене.