Passe o comprimento do argumento na substituição do comando bash

1

Estou tentando escrever uma função bash rápida que preencha um README.md com $1\n seguido de sublinhado o comprimento de $1 .

O código encontrado em outras perguntas do stackexchange mostrou que, para imprimir um caractere <n> times, use

printf '=%.0s' {1..<n>}

e, de fato, isso funciona (obviamente substituindo <n> por um número).

Para criar meu README.md, achei que a função seria algo assim:

make_readme() {
    echo "$1
$(printf '=%.0s' {1..${#1}})" > README.md
}

make_readme "Some project"

Isso, no entanto, produz um arquivo com este texto:

Some project
=

Até onde eu sei, ${#1} dentro do $(...) está sendo substituído pela string vazia. Meu palpite é que as substituições de comandos recebem seus próprios escopos de argumentos e, como não há argumentos passados para a substituição, $1 está sendo substituído por nada.

Eu finalmente consegui algumas soluções alternativas:

make_readme() {
    underline="printf '=%.0s' {1..${#1}}"
    echo "$1
$(eval "$underline")" > README.md
}

ou

make_readme() {
    echo "$1" > README.md
    printf '=%.0s' {1..${#1}} >> README.md
}

mas parece que deve haver uma maneira de fazer isso em uma linha.

    
por dfoverdx 18.10.2018 / 22:41

2 respostas

3

Sugestão:

#!/bin/bash

make_readme () {
    printf '%s\n%s\n' "$1" "$( eval "printf '=%.0s' {1..${#1}}" )"
}

make_readme >README.md

ou, se chamar um utilitário externo, ok,

#!/bin/bash

make_readme () {
    # print $1, then replace all characters in it with = and print again
    sed 'p; s/./=/g' <<<"$1"
}

make_readme >README.md
    
por 18.10.2018 / 23:19
0

Tente

printf "%s\n%*.*s\n" "$1" ${#1} ${#1} $(printf "%.0s=" {1..30})
Some project
============
    
por 18.10.2018 / 23:19