sed whitespace correspondência confusão

7
echo ' 1 2     3  '|sed 's/[[:space:]]*/_/g'

Eu quero ver _1_2_____3__ como a saída. Em vez disso, estou vendo _1_2_3_ como a saída. O que estou fazendo errado ??

EDITAR
A outra coisa me confundindo, que esqueci de colocar no exemplo acima, é o porquê disso:

echo ' test1 test2  ' | sed 's/[[:space:]]*/_/g'

mostra isso:

_t_e_s_t_1_t_e_s_t_2_

Como pode [[:space:]] corresponder entre t e e e s ...?

    
por BenjiWiebe 16.08.2014 / 20:26

3 respostas

13

Porque você usa * , o que significa que corresponde a 0 ou mais espaços. Então, zero ou vários espaços são substituídos por um sublinhado _ .

Tente:

$ echo ' 1 2     3  ' | sed 's/[[:space:]]/_/g'
_1_2_____3__

Lembre-se de que [[:space:]] também corresponde a tabulação, nova linha, retorno de carro.

Nota

por 16.08.2014 / 20:32
5

Você já recebeu uma resposta, mas quero salientar que, em um cenário tão simples, não há necessidade de ser extravagante:

$ echo ' 1 2     3  ' | sed 's/ /_/g'
_1_2_____3__

Se você deseja substituir somente espaços e guias, use o comando \\> também:

$ echo -e " 1\t2     3  " | sed 's/[ \t]/_/g'
_1_2_____3__
    
por 16.08.2014 / 22:26
1

A pergunta é feita explicitamente sobre o sed e é uma questão muito válida sobre a sintaxe do regexp do sed.

Mas, caso a pergunta subjacente seja sobre a substituição de espaços por _ , aqui está uma resposta alternativa usando a "ferramenta certa para o trabalho" para traduzir caracteres, que é tr . ( man tr ).

O comando tr abc 123 substitui os caracteres da primeira lista pelos caracteres correspondentes no segundo. Assim, tr ' ' _ substitui o espaço pelo sublinhado.

$ echo ' 1 2     3  ' | tr ' ' _
_1_2_____3__


Para mostrar o caso mais geral, incluindo vários tipos de espaço em branco como o seu exemplo,
aqui está a saída para apenas traduzir o caractere de espaço normal ' ' para comparação:

echo ' 1 2     3  x\ny\tz' | tr ' ' _        
_1_2_____3__x
y       z

E aqui está a saída ao traduzir todos os caracteres da classe: space: to _ :

echo ' 1 2     3  x\ny\tz' | tr '[:space:]' _
_1_2_____3__x_y_z_

(Observe que não há nova linha no final da saída - e há um _ após o z .)
Isso pode ser escrito explicitamente como tr ' \t\n' _ , que é a forma abreviada de tr ' \t\n' ___ .

$ echo ' 1 2     3  x\ny\tz' | tr ' \t\n' _    
_1_2_____3__x_y_z_
    
por 17.08.2014 / 00:43

Tags