A questão afirma explicitamente que os títulos conterão espaços.
Por motivos de segurança, estou assumindo que os títulos podem conter pontos (pontos);
por exemplo, "The History of 3.14159" ou "Dr. Descoberta de Doolittle ”.
Minhas respostas assumem que existe um algum personagem
isso nunca aparecerá no sumário;
Especificamente, eles assumem que é @
.
Se você tem @
em sua tabela,
substituí-lo por algum personagem que nunca aparece
(por exemplo, #
, ^
, _
, |
etc.).
Se você realmente usa todos os caracteres ASCII,
talvez seja necessário usar uma sequência de caracteres, como <@>
.
Três maneiras de fazer isso com sed
:
Loop:
sed 's/\(.*\)\( \)/@/; :loop; s/ @/ @./; t loop; s/@//'
-
s/\(.*\)\( \)/@/
encontra o último espaço na linha
e insere um @
antes.
-
:loop
é um rótulo, como um marcador de milha.
-
s/ @/ @./
(que é s/␣␣@/␣@./
, para não ambiguidade) diz:
se houver dois espaços antes do @
,
substitua-os por ␣.
(espaço e ponto) e mova o @
entre eles.
-
t loop
diz que, se a substituição acima foi bem sucedida,
volte para o marcador :loop
e repita.
Caso contrário, continue para
-
s/@//
, que remove o @
.
Assim, a linha foo bar
na sua tabela será processada da seguinte forma:
Initial value: foo bar url3
s/\(.*\)\( \)/@/ 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
Números esmagadores:
sed 's/\(.*\)\( \)/@@@@@@@@@@@@@@@@@@@@/; s/ [ @]\{20\}/ /; s/@/./g'
-
%código%
é muito semelhante ao primeiro subcomando
s/\(.*\)\( \)/@@@@@@@@@@@@@@@@@@@@/
na primeira solução;
ele encontra o último espaço na linha
e insere uma cadeia de 20% de caracteress
antes dela.
Este deve ser um número que seja pelo menos tão grande
como o número máximo de pontos que você precisará inserir em uma linha; por exemplo, 80.
Gerenciando uma string de 80 @
caracteres seria estranho;
você pode querer substituir isso com
-
%código%
que insere uma string de cinco
@
sequências,
e, em seguida, substitui cada um deles por uma sequência de 16% de caracteress/\(.*\)\( \)/<@><@><@><@><@>/; s/<@>/@@@@@@@@/g
,
resultando em 5 × 16 = 80 <@>
caracteres.
-
@
encontra uma string de 20 caracteres consecutivos
que são um espaço ou um @
, precedido por um espaço,
e substitui-lo apenas com o espaço anterior.
Substitua s/ [ @]\{20\}/ /
pelo número da etapa anterior.
-
@
substitui cada 20
restante por um ponto.
Assim, a linha s/@/./g
na sua tabela será processada da seguinte forma:
Initial value: foo url1
s/\(.*\)\( \)/@@@@...@@@@/ foo @@@@@@@@@@@@@@@@@@@@ url1
s/ [ @]\{20\}/ / _[↑↑↑↑↑↑remove↑↑↑↑↑↑]
foo @@@@@@ url1
s/@/./g foo ...... url1
Use o "espaço de espera":
sed 's/.*[^ ] /&@/; h; s/ /./g; s/\(\.*\)\./ /; x; G; s/@.*@//'
-
@
é similar aos comandos anteriores;
encontra o fim do título - para ser preciso,
o último lugar onde um caracter não-branco é seguido por um espaço -
e insere um foo
depois.
-
s/.*[^ ] /&@/
copia a linha para o espaço de espera.
-
@
substitui todos os espaços na linha por pontos.
-
h
substitui o último ponto por um espaço.
(Isso precisará mudar se o URL puder conter pontos,
o que, eu acho, é provável.)
-
s/ /./g
troca o espaço padrão e o espaço de espera.
-
s/\(\.*\)\./ /
acrescenta o espaço de espera ao espaço do padrão.
Agora temos, essencialmente, duas cópias da linha.
-
x
mantém a primeira parte da primeira cópia
e a segunda parte da segunda cópia,
se livrando das coisas no meio.
Initial value: foo bar url3
Pattern space Hold space
s/.*[^ ] /&@/ foo bar @ url3
h foo bar @ url3 foo bar @ url3
s/ /./g [email protected] foo bar @ url3
s/\(\.*\)\./ / 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