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