Вопрос явно гласит, что заголовки будут содержать пробелы. В целях безопасности я предполагаю, что заголовки могут содержать точки (точки); например, «История 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
строка в вашей таблице будет обработана следующим образом:
Начальное значение: foo bar url3 s / \ (. * \) \ (\) / \ 1 @ \ 2 / foo bar @ url3 s / @ / @. / foo bar @. url3 s / @ / @. / foo bar @ .. url3 s / @ / @. / foo bar @ .. url3 (Подстановка не удалась, поэтому не зацикливайтесь) s / @ // foo bar .. url3 Конечный результат: foo bar .. url3
Подавляющие цифры:
sed 's/\(.*\)\( \)/\1@@@@@@@@@@@@@@@@@@@@\2/; s/ [ @]\/ /; s/@/./g'
s/\(.*\)\( \)/\1@@@@@@@@@@@@@@@@@@@@\2/
очень похоже на первую s
подкоманду в первом решении; он находит последний пробел в строке и вставляет перед ним строку из 20 @
символов. На самом деле это должно быть число, по крайней мере равное максимальному количеству точек, которое вам когда-либо понадобится вставить в одну строку; например, 80. Управление строкой из 80 @
символов было бы неудобно; вы можете заменить это s/\(.*\)\( \)/\1<@><@><@><@><@>\2/; s/<@>/@@@@@@@@/g
который вставляет строку из пяти <@>
последовательностей, а затем заменяет каждую из них строкой из 16 @
символов, в результате чего получается 5 × 16 = 80 @
символов.
s/ [ @]\/ /
находит строку из 20 последовательных символов, которые являются либо пробелом, либо пробелом @
, которому предшествует пробел, и заменяет его только предыдущим пробелом. Замените 20
на число из предыдущего шага. s/@/./g
заменяет все оставшиеся @
точки.
Поэтому foo
строка в вашей таблице будет обработана следующим образом:
Initial value: foo url1 s/\(.*\)\( \)/\1@@@@...@@@@\2/ foo @@@@@@@@@@@@@@@@@@@@ url1 s/ [ @]\/ / _[↑↑↑↑↑↑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