У питанні прямо вказано, що заголовки будуть містити пробіли. З метою безпеки я припускаю, що заголовки можуть містити крапки (періоди); наприклад, "Історія 3.14159" або "Dr. Відкриття Doolittle ”. Мої відповіді припускають, що є якийсь символ, який ніколи не з’явиться в змісті; конкретно, вони припускають, що це так @
. Якщо у вас є @
в таблиці, замініть його на який - то символ , який ніколи не з'являється (наприклад, #
, ^
, _
, |
і т.д.). Якщо ви дійсно використовуєте кожен символ ASCII, можливо, вам доведеться використовувати послідовність символів, наприклад <@>
.
Три способи зробити це за допомогою sed
:
Петля:
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/ [ @]\{20\}/ /; s/@/./g'
s/\(.*\)\( \)/\1@@@@@@@@@@@@@@@@@@@@\2/
дуже схожий на першу s
підкоманду в першому рішенні; він знаходить останній пробіл у рядку і вставляє @
перед ним рядок з 20 символів. Насправді це повинно бути число, принаймні таке велике, як максимальна кількість точок, які вам коли-небудь знадобиться вставити в одному рядку; наприклад, 80. Управління рядком з 80 @
символів було б незручно; ви можете замінити це на
s/\(.*\)\( \)/\1<@><@><@><@><@>\2/; s/<@>/@@@@@@@@/g
який вставляє рядок з п'яти <@>
послідовностей, а потім замінює кожну з них рядком з 16 @
символів, в результаті чого 5 × 16 = 80 @
символів.
s/ [ @]\{20\}/ /
знаходить рядок з 20 послідовних символів, який є або пробілом, або an @
, якому передує пробіл, і замінює його лише попереднім пробілом. Замініть 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