shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bulk] Re: [shell-script] printf em um loop while só funcionou com e


From: Paulo Bettega
Subject: Re: [Bulk] Re: [shell-script] printf em um loop while só funcionou com eval
Date: Mon, 02 Feb 2015 21:57:14 -0200
User-agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Thunderbird/31.4.0

Olá Sidney, valeu a idéia, todos os pontos de vista são bem-vindos :)
Abraços Paulo Bettega


On 02-02-2015 19:14, Sidney Souza address@hidden [shell-script] wrote:
Cheguei um tanto tarde e pelo visto já foram colocadas diversas soluções kkkk, 
mas como a que pensei
não foi citada, segue a ideia:

sed -r "s|'(.*)' ([0-9]+) ([0-9]+) ([0-9]+)|\1 \2/\3/\4|g" <<<$"'Data: ' $d1 
$m1 $ano
'Outra Data: ' $d2 $m2 $ano
'Mais uma data: ' $d3 $m3 $ano"

PS: Não funciona com array, mas lhe permite eliminar aquela interação do while 
visto que o
processamento é simples e pode ser feito tranquilamente usando uma string e o 
sed.

------------------------------------------------------
http://www.politicos.org.br

2015-02-01 12:38 GMT-02:00 'Julio C. Neves' address@hidden 
<mailto:address@hidden>
[shell-script] <address@hidden <mailto:address@hidden>>:

    __

    É por isso que sempre digo que nunca se deve perguntar:
    "Dá para fazer em Shell?"

    A pergunta correta é:
    "Qual é a melhor maneira de fazer em Shell?"

    Abcs,
    Julio
    *@juliobash**
    Próximos cursos de Shell*
    *Cidade        LocalPeríodo*
    *Rio de JaneiroEDX <http://edx.srv.br/>09 a 13/03/15*
    *São Paulo 4Linux 
<http://www.4linux.com.br/cursos/programacao-em-shell-script>23 a 27/03/15 *
    Dou treinamento de /Shell/ em qualquer cidade.
    Para mais detalhes, me mande um e-mail <mailto:address@hidden>.


    Em 1 de fevereiro de 2015 12:21, Paulo Bettega address@hidden
    <mailto:address@hidden> [shell-script] <address@hidden
    <mailto:address@hidden>> escreveu:

        Olá Julio, valeu as dicas. O operador ternário tem no Programação Shell 
Linux :)
        Esse operador realmente não lembro de usar, e aí vai ficando esquecido.
        O shell tem tantas maneiras de fazer a mesma coisa que na hora de 
escrever
        acabo usando o trivial.

        Abraços Paulo Bettega


        On 31-01-2015 20:55, 'Julio C. Neves' address@hidden 
<mailto:address@hidden>
        [shell-script] wrote:
         > Fala Paulo,
         > interessante essa discussão do printf... Mas como aparentemente vc 
já resolveu esse
        pepino, queria
         > te dar duas dicas:
         >
         > A cada texto lido, vc compara com tabulação. Eu guardaria tudo num 
array ou até em uma
        variável e
         > para pegar o tamanho do maior usaria wc -L.
         >         -L, --max-line-length
         >                print the length of the longest line
         > Caso vc não queira fazer assim, useo operador ternário que é 
infinitamente mais veloz. Faça:
         > $ tabulacao=8
         > $ texto=fgergewhwthwrthw
         > $ tabulacao=$((tabulacao < ${#texto} ? ${#texto}+2 : $tabulacao)) # 
esse é o ternário
         > $ echo $tabulacao
         > 18
         >
         >
         >
         > Abcs,
         > Julio
         > *@juliobash**
         > Próximos cursos de Shell*
         > *Cidade        LocalPeríodo*
         > *Rio de JaneiroEDX <http://edx.srv.br/>09 a 13/03/15*
         > *São Paulo 4Linux 
<http://www.4linux.com.br/cursos/programacao-em-shell-script>23 a
        27/03/15 *
         > Dou treinamento de /Shell/ em qualquer cidade.
         > Para mais detalhes, me mande um e-mail <mailto:address@hidden
        <mailto:address@hidden>>.
         >
         >
         > Em 31 de janeiro de 2015 19:37, Paulo Bettega address@hidden
        <mailto:address@hidden>
         > <mailto:address@hidden <mailto:address@hidden>> [shell-script]
        <address@hidden <mailto:address@hidden>
         > <mailto:address@hidden <mailto:address@hidden>>> escreveu:
         >
         >     Olá Ronaldo, valeu a lembrança do set -x, realmente não lembrei 
de verificar com o debug.
         >
         >     Colei apenas as linhas referentes ao printf.
         >     set -x
         >     d1=4;d2=10;d3=5;m1=5;m2=3;m3=12;ano=2015
         >     while read linha; do printf '%20s%02d/%02d/%d\n' $linha
         >     done <<<"'Data: ' $d1 $m1 $ano
         >     'Outra Data: ' $d2 $m2 $ano
         >     'Mais uma data: ' $d3 $m3 $ano"
         >     + read linha
         >     + printf '%20s%02d/%02d/%d\n' ''\''Data:' \' 4 5 2015
         >                     'Data:00/04/5
         >                       201500/00/0
         >     + read linha
         >     + printf '%20s%02d/%02d/%d\n' ''\''Outra' Data: \' 10 3 2015
         >     -su: printf: Data:: invalid number
         >                     'Outra00/00/10
         >                          32015/00/0
         >     + read linha
         >     + printf '%20s%02d/%02d/%d\n' ''\''Mais' uma data: \' 5 12 2015
         >     -su: printf: uma: invalid number
         >     -su: printf: data:: invalid number
         >                      'Mais00/00/0
         >                          512/2015/0
         >
         >     Parece que o shel adiciona alguns apóstrofos, e os apóstrofos 
que eu coloquei
         >     pra proteger o texto acho que são os que aparecem escapados.
         >
         >
         >     Com eval e o \n escapado dá pra ver que o shell monta a linha
         >     como eu imaginei sem o eval: printf '%20s%02d/%02d/%d\n' 'Data: 
' 4 5 2015
         >
         >     while read linha; do eval printf '%20s%02d/%02d/%d\\n' $linha
         >     done <<<"'Data: ' $d1 $m1 $ano
         >     'Outra Data: ' $d2 $m2 $ano
         >     'Mais uma data: ' $d3 $m3 $ano"
         >     + read linha
         >     + eval printf '%20s%02d/%02d/%d\\n' ''\''Data:' \' 4 5 2015
         >     ++ printf '%20s%02d/%02d/%d\n' 'Data: ' 4 5 2015
         >                     Data: 04/05/2015
         >     + read linha
         >     + eval printf '%20s%02d/%02d/%d\\n' ''\''Outra' Data: \' 10 3 
2015
         >     ++ printf '%20s%02d/%02d/%d\n' 'Outra Data: ' 10 3 2015
         >               Outra Data: 10/03/2015
         >     + read linha
         >     + eval printf '%20s%02d/%02d/%d\\n' ''\''Mais' uma data: \' 5 12 
2015
         >     ++ printf '%20s%02d/%02d/%d\n' 'Mais uma data: ' 5 12 2015
         >            Mais uma data: 05/12/2015
         >
         >
         >     Aqui vai um esboço do script. O número de linhas que serão 
impressas pode
         >     variar, por isso pensei em colocar o printf dentro do loop.
         >     Além disso o alinhamento do texto deve ser conforme a variável 
$texto mais longa.
         >     (aqui teve outro problema. As outras linhas ficavam dois 
caracteres desalinhadas
         >     com a linha mais longa. Somando dois na $tabulacao resolveu).
         >     Pensei nisso mais como um exercício, mas no fim das contas ficou 
bem mais
         >     complicado do que eu achei que ficaria.
         >
         >     #!/bin/bash
         >
         >     tabulacao=1
         >     datas=()
         >     while true; do
         >               read -p "Texto: " texto
         >               # Guarda o maior comprimento de $texto para usar
         >               # como alinhamento no printf.
         >               [ "${#texto}" -gt "$tabulacao" ] && 
tabulacao=$((${#texto}+2))
         >               [ "$texto" = 'fim' ] && break
         >               texto="$texto: "
         >               read -p "Dia: " dia
         >               read -p "Mês: " mes
         >               read -p "Ano: " ano
         >               datas=( "${datas[@]}" "'$texto' $dia $mes $ano" )
         >     done
         >
         >     for i in $(seq ${#datas[*]}); do
         >               eval 'printf "%${tabulacao}s%02d/%02d/%d\n"' 
${datas[$((i-1))]}
         >     done
         >
         >
         >     Abraços Paulo Bettega
         >
         >
         >     On 31-01-2015 11:39, Ronaldo Ferreira de Lima address@hidden
        <mailto:address@hidden> <mailto:address@hidden <mailto:address@hidden>>
         >     [shell-script] wrote:
         >       > É possível verificar o que aconteceu usando o "modo debug" 
set -x, o
         >       > grande problema foram os espaços "extras". Para evitar essas 
surpresas é
         >       > recomendável utilizar o método tradicional:
         >       >
         >       > printf '%20s: %02d/%02d/%d\n' "$str" $dia $mes $ano
         >       >
         >       > []'s
         >       > --
         >       > "Não manejo bem as palavras
         >       > Mas manipulo bem as strings."
         >       > ------------------------------
         >       > http://tecnoveneno.blogspot.com
         >       >
         >
         >
         >      > On Sat, Jan 31, 2015 at 02:49:55AM -0200, Paulo Bettega 
address@hidden
        <mailto:address@hidden>
         >     <mailto:address@hidden <mailto:address@hidden>> [shell-script] 
wrote:
         >      >  > Olá pessoal, tentei fazer esse loop, já que a linha do 
printf é sempre a mesma.
         >      >  > (Sei que nesse caso o loop é praticamente igual a escrever 
uma linha de
         >      >  > printf para cada linha do 'here strings', mas no futuro 
pretendo colocar
         >      >  > os dados num vetor).
         >      >  >
         >      >  > d1=4;d2=10;d3=5;m1=5;m2=3;m3=12;ano=2015
         >      >  > while read linha; do printf '%20s%02d/%02d/%d\n' $linha
         >      >  > done <<<"'Data: ' $d1 $m1 $ano
         >      >  > 'Outra Data: ' $d2 $m2 $ano
         >      >  > 'Mais uma data: ' $d3 $m3 $ano"
         >      >  >
         >      >  > A saída que eu queria era essa (talvez perca o 
alinhamento, os : são alinhados)
         >      >  > Data: 04/05/2015
         >      >  > Outra Data: 10/03/2015
         >      >  > Mais uma data: 05/12/2015
         >      >  >
         >      >  > mas o resultado foi esse
         >      >  > 'Data:00/04/5
         >      >  > 201500/00/0
         >      >  > bash: printf: Data:: invalid number
         >      >  > 'Outra00/00/10
         >      >  > 32015/00/0
         >      >  > bash: printf: uma: invalid number
         >      >  > bash: printf: data:: invalid number
         >      >  > 'Mais00/00/0
         >      >  > 512/2015/0
         >      >  >
         >      >  > Não entendi porque aconteceu isso, me pareceu tudo certo, 
pois o texto está
         >      >  > entre aspas simples, então o printf deveria reconhecer o 
texto todo como string
        %20s
         >      >  > e as três variáveis com a formatação da data %02d/%02d/%d
         >      >  >
         >      >  > Não sei porque, mas achei que o printf não estava 
recebendo a variável $linha
        como deveria,
         >      >  > então "chutei" um eval antes do printf, e o resultado foi 
animador:
         >      >  >
         >      >  > while read linha; do eval printf '%20s%02d/%02d/%d\n' 
$linha
         >      >  > done <<<"'Data: ' $d1 $m1 $ano
         >      >  > 'Outra Data: ' $d2 $m2 $ano
         >      >  > 'Mais uma data: ' $d3 $m3 $ano"
         >      >  > Data: 04/05/2015n Outra Data: 10/03/2015n Mais uma data: 
05/12/2015n
         >      >  >
         >      >  > O resultado foi o que eu queria, apenas não quebrou a 
linha porque o \n
         >      >  > foi interpretado como "escapen", eu acho.
         >      >  > Então coloquei outro escape antes do \n e deu certo:
         >      >  >
         >      >  > while read linha; do eval printf '%20s%02d/%02d/%d\\n' 
$linha
         >      >  > done <<<"'Data: ' $d1 $m1 $ano
         >      >  > 'Outra Data: ' $d2 $m2 $ano
         >      >  > 'Mais uma data: ' $d3 $m3 $ano"
         >      >  > Data: 04/05/2015
         >      >  > Outra Data: 10/03/2015
         >      >  > Mais uma data: 05/12/2015
         >      >  >
         >      >  > Outro jeito que deu certo foi colocar apenas 'printf 
[formato]' entre aspas,
         >      >  > eval "printf '%20s%02d/%02d/%d\n'" $linha
         >      >  > ou
         >      >  > eval 'printf "%20s%02d/%02d/%d\n"' $linha
         >      >  >
         >      >  > No fim das contas o loop deu certo, mas eu não entendi 
porque.
         >      >  > Eu realmente achei que apenas colocando o printf dentro do 
loop teria que
        funcionar.
         >      >  > Porque o printf não reconhece direito a variável $linha 
sem o eval?
         >
         >
         >
         >     ------------------------------------
         >
         >
         >
         >
         >
        
----------------------------------------------------------------------------------------------------
         > Enviado por: "Julio C. Neves" <address@hidden 
<mailto:address@hidden>>
         >
        
----------------------------------------------------------------------------------------------------





----------------------------------------------------------------------------------------------------
Enviado por: Sidney Souza <address@hidden>


reply via email to

[Prev in Thread] Current Thread [Next in Thread]