Como obtenho números zero-padded usando a expansão de contraventamento? {1..30} com 01 02 03 etc [duplicado]

12

Ao fazer:

for i in {1..30}; do echo $i; grep $i/Aug access.log | sort -u | wc -l; done;

o problema é que é assim:

1/Aug      # should be 01/Aug
2/Aug      # should be 02/Aug
...

Como ter for i in {1..30} dando 01, 02, 03 em vez de 1, 2, 3?

    
por Basj 03.10.2017 / 16:53

1 resposta

21

Em bash e zsh , use {01..30} :

$ for i in {01..30}; do
      echo $i
      # other code using "$i"
  done
01
02
03
04
05
06
(etc.)

Em ksh93 , use {0..30%02d} .

Em sh , ou qualquer outro shell POSIX, use

i=0
while [ "$(( i += 1 ))" -le 30 ]; do
    zi=$( printf '%02d' "$i" )
    echo "$zi"
    # other code using "$zi"
done

Sua variável i também precisa de citação:

for i in {01..30}; do
    echo "$i"
    grep "$i/Aug" access.log | sort -u | wc -l
done

Ou, alternativamente,

sed -E -n 's#^.*([0-9][0-9]/Aug).*$##p' access.log | sort | uniq -c

ou

grep -o '[0-9][0-9]/Aug' access.log | sort | uniq -c

Esse pipeline único (sem loop) produziria as datas correspondentes a 2-digit-number/Aug e o número de entradas de log de acesso correspondentes a essa string de data.

Isso é feito extraindo toda a ocorrência de [0-9][0-9]/Aug do arquivo, classificando-os e permitindo que uniq conte quantas vezes cada um ocorre.

A variação grep , embora indiscutivelmente mais agradável do que o comando sed , fornecerá números muito grandes se a cadeia de data ocorrer várias vezes em uma linha.

    
por 03.10.2017 / 16:56

Tags