Zero Padded Files
I've written a script (Bash 4.2.37) to convert a whole heap of audio files to a common format, and move them to a particular directory. I've done some limited testing and so far it works like a champ, but a couple of finer points have me scratching my head.
Specifically, this snippet: Code:
#find greatest increment amongst files When I first ran the script, $greatest had a value of 0008 and $i a value of 9. The second go, $greatest was 0012, $i 13. Which is as it should be. Except not if Bash treats numbers with leading zeros as octal. The $greatest+3 bit seems to work just fine, but it irks me. I chased my own tail for an age trying to make something like (($greatest++)) work. It didn't. |
Well, you could remove the leading zeros with the ${greatest##0} couldn't you? That might help.
|
That's the weird thing. I didn't remove the leading zeros, but they're gone when I use $i in my script.
Maybe I should clear the directory and start at 0. It was only a circumstance that 0008 was the largest number in the directory. Did Bash automatically determine that I wasn't using octal because 0008 would be invalid? |
I just took a quick look at pinfo bash, and was reminded that you can explicitly state your number base by preceding the number with a specific base, so, for example:
Code:
$ echo $((10#017)) " != " $((017)) Code:
$ for ((i=0;i<21;i=i+3)); do j="0000"${i};echo ${i} "=" ${j: -4};done <edit> I forgot the printf command!:redface: Code:
$ for ((i=0;i<=21;i=i+3)); do printf "%2d = %04d\n" ${i} ${i};done |
That makes sense. Have I stumbled across a convenient shortcut or will this bite me in the ass?
Counting on my toes, 0012 should convert to 10 rather than 13. Since my script is returning 13 (the value I expect) for $i, it's making a sort of literal conversion rather than a mathematical conversion. If I don't have to explicitly strip zero padding from the filenames, I will opt for the lazy solution and leave it as it stands. |
This doesn't work for me:
Code:
~/tmp/music$ ls |
No, ntubski. That's why I don't particularly understand it.
Here's the code that names my files: Code:
for file in ${files[@]} That's why I think it shouldn't work. My understanding is that it should have broken the first time I ran the script when I had 0008 files (which I put there manually). |
Quote:
Back to the original question, how about you isolate the problem: make a new script in an empty directory: Code:
#!/bin/bash Code:
./next-name.bash: line 9: ((: i=0008: value too great for base (error token is "0008") |
I get that same error running your script.
Code:
line 9: ((: i=0008: value too great for base (error token is "0008") |
The padding should be fine. It counts the number of characters in the base filename and if less than four adds as many zeros as needed to make it four digits.
|
Quote:
And the padding code is fine, I just had a temporary comprehension failure. |
I think it's likely that your first code and the first output was different. Even if 0008 was not treated as octal "i" would not have a value of 9.
Code:
greatest=0008 |
Quote:
Code:
while [ x"$greatest" != x0 ] && [ x"$greatest" != x"${greatest#0}" ]; do Code:
greatest=${greatest#"${greatest%%[1-9]*}"} Quote:
|
Quote:
Also extended globbing would be a better solution for trimming leading zeros: Code:
shopt -s extglob |
As mentioned in passing by konsolebox, when a number has a leading zero, the shell treats it as an octal value. Any arithmetic operation on a number that includes an 8 or 9 will result in an error, and others will probably give you incorrect values.
Edit: :doh: I just noticed that the OP actually said it first. Oh well. The best way to avoid this is to strip the leading zeroes off before doing any math, and only re-pad them when you really need it. http://mywiki.wooledge.org/ArithmeticExpression http://mywiki.wooledge.org/BashFAQ/018 The leading base string is another option instead of stripping them off, but you'll still have to worry about re-padding the results afterwards. |
All times are GMT -5. The time now is 10:29 AM. |