Estou tentando escrever um comando sed para substituir espaços excessivos em um arquivo. Cada palavra deve ter apenas um espaço entre as palavras, mas os espaços iniciais e tabulações devem ser deixados em paz. Então o arquivo:
This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.
Se tornará:
This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.
Eu tentei variações de
/^[ \t]*/!s/[ \t]+/ /g
Qualquer idéia seria apreciada.
Responder1
$ sed 's/\>[[:blank:]]\{1,\}/ /g' file
This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.
A expressão que usei corresponde a um ou vários [[:blank:]]
(espaços ou tabulações)depois de uma palavrae os substitui por um único espaço. Corresponde \>
ao limite de largura zero entre um caractere de palavra e um caractere que não é de palavra.
Isso foi testado com o nativo do OpenBSD sed
, mas acho que deveria funcionar com o GNU sed
também. GNU sed
também usa \b
para combinar limites de palavras.
Você também pode usar sed -E
para encurtar isso para
sed -E 's/\>[[:blank:]]+/ /g' file
Novamente, se \>
não funcionar para você com GNU sed
, use \b
.
Observe que, embora o texto acima classifique seu texto de exemplo da maneira correta, isso nãobastantetrabalho para remover espaços após a pontuação, como após a primeira frase em
This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.
Para isso, uma variante um pouco mais complicada resolveria o problema:
$ sed -E 's/([^[:blank:]])[[:blank:]]+/\1 /g' file
This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.
Isso substitui qualquer caractere que não esteja em branco seguido por um ou mais caracteres em branco pelo caractere que não esteja em branco e um único espaço.
Ou, usando o padrão sed
(e uma otimização muito pequena, pois só fará a substituição se houverdois ou maisespaços/tabulações após o não-espaço/tabulação),
$ sed 's/\([^[:blank:]]\)[[:blank:]]\{2,\}/\1 /g' file
This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.
Responder2
POSIXamente:
sed 's/\([^[:space:]]\)[[:space:]]\{1,\}/\1 /g; s/[[:space:]]*$//'
Que substitui qualquer sequência de um ou mais caracteres de espaço em branco após um não-espaço em branco, por esse não-espaço em branco e um único caractere SPC, e remove os caracteres de espaço em branco à direita, o que cobriria linhas em branco e linhas com espaço em branco à direita (incluindo os CRs encontrados em o final das linhas provenientes de arquivos de texto da Microsoft).