preenchimento de espaços em branco finais em uma string com outro caractere

11

Gostaria de produzir hello world com mais de 20 caracteres.

printf "%-20s :\n\n" 'hello world!!'

# Actual output
hello world!!        :

# Wanted output
hello world!!========:

No entanto, não quero concluir com espaços, mas com " = ". Como eu faço isso?

    
por smarber 18.10.2017 / 11:47

6 respostas

9

Resposta atualizada para ser uma solução mais geral. veja também minha outra resposta abaixo usando apenas a expansão de chave de concha e pritnf .

$ str='Hello World!'
$ sed -r ':loop; s/ (=*):$/=:/; t loop' <<< "$(printf '%-20s:\n' "$str" )"
Hello World!========:

Como funciona?

este (=*):$/ captura um espaço, um ou mais = que é seguido por dois pontos : no final de sua entrada; nós fazemos o conjunto de = como uma correspondência de grupo e será sua referência de volta.

Com :loop , definimos um rótulo denominado loop e, com t loop , ele passa para esse rótulo quando um s/ (=*):$/=:/ fez uma substituição bem-sucedida;

Na peça de substituição com =: , ele sempre aumentará o número de = s e retornará o próprio ponto até o final da string.

    
por 18.10.2017 / 12:30
19
filler='===================='
string='foo'

printf '%s\n' "$string${filler:${#string}}"

foo=================

${#string} é o comprimento do valor $string e ${filler:${#string}} é a subseqüência de $filler do deslocamento ${#string} em diante.

A largura total da saída será igual à largura máxima de $filler ou $string .

A string de preenchimento pode, em sistemas que possuem jot , ser criada dinamicamente usando

filler=$( jot -s '' -c 16 '=' '=' )

(para 16 = em uma linha). Sistemas GNU podem usar seq :

filler=$( seq -s '=' 1 16 | tr -dc '=' )

Outros sistemas podem usar o Perl ou alguma outra maneira mais rápida de criar a string dinamicamente.

    
por 18.10.2017 / 12:33
17
printf "%.20s:\n\n" "$str========================="

em que %.20s é o formato de truncamento da string

    
por 18.10.2017 / 12:35
11

Uma maneira de fazer isso:

printf "====================:\r%s\n\n" 'hello world!!'
    
por 18.10.2017 / 11:55
5

Uma abordagem Perl:

$ perl -le '$k="hello world!!"; while(length($k)<20){$k.="=";} print "$k\n"'
hello world!!=======

Ou melhor, @SatoKatsura apontou nos comentários:

perl -le '$k = "hello world!!"; print $k, "=" x (20-length $k), "\n"'

Se você precisar oferecer suporte a caracteres de multibyte UTF, use:

PERL_UNICODE='AS' perl -le '$k = "hello world!!"; print $k, "=" x (20-length $k), "\n"'

Mesma ideia no shell:

v='hello world!!'; while [ ${#v} -lt 20 ]; do v="$v""="; done; printf '%s\n\n' "$v"
    
por 18.10.2017 / 12:20
5

Outra maneira é usar apenas o comando printf e gerar o padrão de preenchimento de caractere primeiro Shell Brace Expansion (Você pode colocar fim com um número ≥ área de formatação que deseja imprimir em {1..end} ) e obter apenas todos os primeiros caracteres %.1s , que é = se imprima apenas a primeira área de 20 caracteres de comprimento desse %.20s . Esta é uma maneira melhor de ter personagens / palavras repetidas em vez de duplicá-las.

printf '%.20s:\n' "$str$(printf '%.1s' ={1..20})"
Hello World!!=======:

Explicações:

Normalmente, como Expansão de contraventamentos , o shell está expandindo {1..20} da seguinte forma se nós os imprimimos.

printf '%s ' {1..20}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 

Portanto, ao adicionar um sinal de igual a ele, ={1..20} , o shell será expandido da seguinte forma.

printf '%s ' ={1..20}
=1 =2 =3 =4 =5 =6 =7 =8 =9 =10 =11 =12 =13 =14 =15 =16 =17 =18 =19 =20 

E com printf '%.1s' , que na verdade significa printf '%WIDE.LENGTH' , estamos imprimindo apenas um LENGTH dos acima, com o padrão 1 WIDE . então resultará = s apenas e 20 vezes se repetirá.

Agora, com printf '%.20s:\n' , estamos imprimindo apenas o comprimento 20 de $str e, se o comprimento de $str < 20, o restante levará de = s gerados para preenchimento em vez de espaços.

    
por 19.10.2017 / 10:04