3

I am trying to write a BASH script that downloads some transcripts of a podcast with cURL. All transcript files have a name that only differs by three digits: filename[three-digits].txt

  • from filename001.txt
  • to.... filename440.txt.

I store the three digits as a number in a variable and increment the variable in a while loop. How can I increment the number without it losing its leading zeroes?

#!/bin/bash
clear

# [...] code for handling storage

episode=001
last=440

secnow_transcript_url="https://www.grc.com/sn/sn-"
last_token=".txt"

while [ $episode -le $last ]; do
    curl -X GET $secnow_transcript_url$episode$last_token > # storage location
    episode=$[$episode+001];
    sleep 60 # Don't stress the server too much!
done

I searched a lot and discovered nice approaches of others, that do solve my problem, but out of curiosity I would love to know if there is solution to my problem that keeps the while-loop, despite a for-loop would be more appropriate in the first place, as I know the range, but the day will come, when I will need a while loop! :-)

#!/bin/bash
for episode in $(seq -w 01 05); do
    curl -X GET $secnow_transcript_url$episode$last_token > # ...
done

or for just a few digits (becomes unpractical for more digits)

#!/bin/bash
for episode in 00{1..9} 0{10..99} {100..440}; do
    curl -X GET $secnow_transcript_url$episode$last_token > # ...
done
Community
  • 1
  • 1
Senkaku
  • 197
  • 2
  • 10

3 Answers3

6

You can use $((10#$n)) to remove zero padding (and do calculations), and printf to add zero padding back. Here are both put together to increment a zero padded number in a while loop:

n="0000123"
digits=${#n} # number of digits, here calculated from the original number
while sleep 1
do
    n=$(printf "%0${digits}d\n" "$((10#$n + 1))")
    echo "$n"
done
that other guy
  • 116,971
  • 11
  • 170
  • 194
1

for ep in {001..440} should work.

But, as you want a while loop: let printf handle leading zeroes

while (( episode <= last )); do
    printf -v url "%s%03d%s" $secnow_transcript_url $episode $last_token
    curl -X GET $url > # storage location
    (( episode++ ))
    sleep 60 # Don't stress the server too much!
done
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • That does not work for me as it url becomes `... 8000 9000 10000 11000 ...` – Senkaku Feb 06 '14 at 02:27
  • Nevertheless, I also learned some syntax through you. The -v parameter of printf was new to me and also the dollar-sign free syntax. Thank you. – Senkaku Feb 06 '14 at 02:40
  • +1 for dealing with padding only on _output_ (therefore, the start/end values should also be unpadded - i.e., `episode=1` - as a padded value such as `010` could get you in trouble); note that bash versions < 4 (e.g., on OS X 10.9) do _not_ support padding in brace expansion, so that `{001..440}` yields `1 2 ...` rather than `001 002 ...`. – mklement0 Feb 06 '14 at 03:16
  • 1
    @th3m3s: The dollar-sign free syntax is called arithmetic evaluation (`((...))` - as a Boolean test) / arithmetic expansion (`$((...))` - as an expression returning a value) and the latter should be used instead of the deprecated `$[...]` syntax. – mklement0 Feb 06 '14 at 03:23
0

Will this do?

#!/bin/bash

i=1
zi=000000000$i
s=${zi:(-3)}
echo $s
Geordee Naliyath
  • 1,799
  • 17
  • 28
  • The problem of my code is, that it removes the leading zeroes after the first incrementation, so that this happens: `001 2 3 ... 10 11 ... 101 102 ...`. I don't need to strip leading zeroes, but nevertheless I have learned through you, that I can read a variable from the rear, thanks. – Senkaku Feb 06 '14 at 02:34
  • Use a simple integer (i) for increment operation, and use the padded integer (s) for GET operation. – Geordee Naliyath Feb 06 '14 at 03:18