Вопрос явно гласит, что заголовки будут содержать пробелы.
В целях безопасности я предполагаю, что заголовки могут содержать точки (точки); например, «История 3.14159» или «Доктор Открытие Дулиттла ».
Мои ответы предполагают, что есть какой-то символ, который никогда не появится в оглавлении; в частности, они предполагают, что это @
.
Если в вашей таблице есть @
, замените его каким-нибудь символом, который никогда не появляется (например, #
, ^
, _
, |
и т.д.).
Если вы действительно используете каждый символ ASCII, вам может потребоваться использовать последовательность символов, например <@>
.
Три способа сделать это с помощью sed
:
Loop:
sed 's/\(.*\)\( \)/\1@\2/; :loop; s/ @/ @./; t loop; s/@//'
s/\(.*\)\( \)/\1@\2/
находит последний пробел в строке и вставляет перед ним символ @
.
:loop
- это метка, похожая на маркер мили.
s/ @/ @./
(то есть s/␣␣@/␣@./
, для неоднозначности) говорит, что если перед @
есть два пробела, замените их на ␣.
(пробел и точка) и переместите @
между ними.
t loop
говорится, что если вышеуказанная замена прошла успешно, вернитесь к маркеру :loop
и повторите.
В противном случае продолжайте
s/@//
, который удаляет @
.
Таким образом, foo bar
в вашей таблице будет обрабатываться следующим образом:
Initial value: foo bar url3
s/\(.*\)\( \)/\1@\2/ foo bar @ url3
s/ @/ @./ foo bar @. url3
s/ @/ @./ foo bar @.. url3
s/ @/ @./ foo bar @.. url3 (Substitution fails, so don’t loop)
s/@// foo bar .. url3
Final output: foo bar .. url3
Подавляющие цифры:
sed 's/\(.*\)\( \)/\1@@@@@@@@@@@@@@@@@@@@\2/; s/ [ @]\{20\}/ /; s/@/./g'
s/\(.*\)\( \)/\1@@@@@@@@@@@@@@@@@@@@\2/
очень похож на первую подкоманду s
в первом решении; он находит последнее место на линии и вставляет строку 20 @
символов перед ним.
На самом деле это должно быть число, по крайней мере равное максимальному количеству точек, которое вам когда-либо понадобится вставить в одну строку; например, 80.
Управление строки 80 @
символы будут неудобно; вы можете заменить это
s/\(.*\)\( \)/\1<@><@><@><@><@>\2/; s/<@>/@@@@@@@@/g
, который вставляет строку из пяти <@>
последовательностей, а затем заменяет каждый из них со строкой 16 @
символов, что приводит к 5 × 16 = 80 @
персонажи.
s/ [ @]\{20\}/ /
находит строку из 20 последовательных символов, которые являются либо пробелом, либо символом @
, которому предшествует пробел, и заменяет его только предыдущим пробелом.
Замените 20
на число из предыдущего шага.
s/@/./g
заменяет каждый оставшийся @
точкой.
Таким образом, строка foo
в вашей таблице будет обработана следующим образом:
Initial value: foo url1
s/\(.*\)\( \)/\1@@@@...@@@@\2/ foo @@@@@@@@@@@@@@@@@@@@ url1
s/ [ @]\{20\}/ / _[↑↑↑↑↑↑remove↑↑↑↑↑↑]
foo @@@@@@ url1
s/@/./g foo ...... url1
Используйте «место для удержания»:
sed 's/.*[^ ] /&@/; h; s/ /./g; s/\(\.*\)\./\1 /; x; G; s/@.*@//'
s/.*[^ ] /&@/
аналогичен предыдущим командам; он находит конец заголовка - если быть точным, последнее место, где за непустым символом следует пробел - и вставляет после него символ @
.
h
копирует строку в область удержания.
s/ /./g
заменяет все пробелы в строке точками.
s/\(\.*\)\./\1 /
заменяет последнюю точку пробелом.
(Это нужно будет изменить, если URL может содержать точки, что, я думаю, вероятно.)
x
меняет пространство образца и пространство удержания.
G
добавляет пространство удержания к пространству шаблона.
Теперь у нас есть, по сути, две копии строки.
s/@.*@//
сохраняет первую часть первой копии и вторую часть второй копии, избавляясь от содержимого посередине.
Initial value: foo bar url3
Pattern space Hold space
s/.*[^ ] /&@/ foo bar @ url3
h foo bar @ url3 foo bar @ url3
s/ /./g foo.bar.@...url3 foo bar @ url3
s/\(\.*\)\./\1 / foo.bar.@.. url3 foo bar @ url3
x foo bar @ url3 foo.bar.@.. url3
G foo bar @ url3 foo.bar.@.. url3 foo.bar.@.. url3
s/@.*@// foo bar .. url3 foo.bar.@.. url3
Final output: foo bar .. url3