Formatação de Printf com formato variável - o que isso faz referência a var?

5

Estou experimentando a formatação printf no bash e passei por esse código:

#/bin/bash
divider===============================
divider=$divider$divider

header="\n %-15s %8s %10s %11s\n"
format=" %-15s %08d %10s %11.2f\n"
width=55

printf "$header" "ITEM NAME" "ITEM ID" "COLOR" "PRICE"

printf "%$width.${width}s\n" "$divider"

printf "$format" \
Triangle 13  red 20 \
Oval 204449 "dark blue" 65.656 \
Square 3145 orange .7

A linha em que estou interessado é a linha que diz:

printf "%$width.${width}s\n" "$divider"

O que essa referência variável está fazendo? O que significa isso?

    
por Allan 24.03.2015 / 01:50

1 resposta

8

O código "%$width.${width}s\n" gera uma string de formato adequada para o consumo por printf

No script que você postou, width recebeu o valor 55 , para que $width e ${width} sejam expandidos por bash para 55 : o primeiro parâmetro inteiro para printf expande codificar%; esse é o formato %55.55s\n , com especificadores de largura e precisão de campo que solicitam exatamente 55 caracteres. Dado o valor da variável %s neste ponto, isso simplesmente imprimirá uma linha de 55 sinais de igual. Uma maneira talvez mais simples de imprimir a mesma coisa seria divider .

A forma mais simples para o especificador de largura de campo é um inteiro: isso pede que perl -e 'print "=" x 55, "\n"' use pelo menos esse número de caracteres para impressão. Se o parâmetro correspondente exigir menos caracteres do que isso para imprimir, a saída será preenchida com espaços.

A forma mais simples para o especificador de precisão é um ponto seguido por um número inteiro: quando aplicado a printf , isso define o número máximo de caracteres a serem impressos. (Tem um significado diferente para tipos numéricos).

Em resposta a um comentário, eu também mencionarei um pouco sobre expansão de variável de shell (a explicação completa pode ser encontrada procurando por "expansão de parâmetro" na documentação do bash, veja também $VAR vs $ {VAR} e para citar ou não citar :

  • Quando uma variável, digamos %s , foi definida, então x se expande para o valor de $x . Se esse valor contiver espaço em branco, a expansão será de várias palavras. É por isso que é importante no código acima, por exemplo, x estar entre aspas duplas: isso força a expansão a ser uma única palavra (caso contrário, "$format" veria um primeiro parâmetro printf , seguido por um argumento %-15s , etc., em vez de receber a string de formatação inteira como um único parâmetro).

  • É permitido escrever %8s em vez de apenas ${x} para expandir a variável $x ; no caso acima, x , é necessário fazer isso porque se alguém tivesse escrito "${width}s" , então o bash tentaria obter o valor da variável "$widths" , o que não é definido, resultando em uma expansão vazia.

por 24.03.2015 / 02:42