2

I'm writing a bash script that generates file names from a spread sheet and then converts existing files to the new ones. I'm already able to do the conversion with a resulting filename 62_02.png as an example. As you can see it contains integers, an underscore and a file extension (which may be an alphanumeric).

I like how succinct this answer is and I've seen this post using awk to do a simple conversion of a purely numeric filename but I'm not sure how I can get it to work with the underscore.

If necessary I also have no problem using sed if that seems practical.

My goal is to have a filename that looks like:

0062_02.png

Many thanks!

Closing information:

I've chosen the solution below for it's greater number of solutions so that another person reading this for their benefit can choose. However, I'd like to mention the answer provided by @cabad is also valid and is probably more friendly a solution to a newbie programmer, IMHO.

Community
  • 1
  • 1
Alex Smith
  • 468
  • 5
  • 22
  • What is the range of input file names? Is `1_1.png` valid? What about `1_01.png`? What should `100_01.png` map to (`0100_01.png` or `00100_01.png` are plausible)? Fixing the one name is trivial: `file="62_02.png"; mv "$file" "00$file";` but you have a wider range of names in mind. – Jonathan Leffler Jul 17 '13 at 21:04
  • All names you have provided are valid. Anything after the underscore is taken directly from the previous filename. The underscore just means that this file is part of a set and generally a set is more than 10, maybe more than 100. But this is more information than you need. – Alex Smith Jul 17 '13 at 21:17
  • Do not use either of the answers in the posts you referenced as both are buggy. – Ed Morton Jul 17 '13 at 21:39
  • @EdMorton, can you provide an explanation as to why? – Alex Smith Jul 17 '13 at 22:13
  • Mostly they don't quote their variable names, but there's other issues too. In general if someone proposes a shell solution and they aren't quoting their variables then you should look at everything else they suggest with a large grain of salt as quoting your variables is one of the most basic tenets of shell programming and if they got that wrong, what else might they be getting wrong? – Ed Morton Jul 18 '13 at 03:21

3 Answers3

4

Try doing this in a :

using :

$ a=62_02.png
$ printf -v newvar %04d_%s ${a%_*} ${a##*_}
echo "$newvar"
0062_02.png

Another concise solution :

$ ( a=62_02.png; IFS=_; printf '%04d_%s\n' $a )
0062_02.png
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
  • 2
    Thanks @sputnick! I like this answer a lot but first can you explain the latter part of the printf line? i.e., `${a%_*} ${a##*_}` What do the % and double ## signs do? – Alex Smith Jul 17 '13 at 21:19
  • 1
    @AlexSmith This [link](http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion) should help. – jaypal singh Jul 18 '13 at 00:58
4

Using awk as requested in question:

echo "62_02.png" | awk -F_ '{ printf("%04d_%s\n", $1, $2); }'

The "-F_" tells awk to use underscore as the field separator. This answer assumes your file names have only one underscore.

EDIT: If your file names can have more than one underscore, then you can do this:

echo "62_02.png" | awk -F_ '{ printf("%04d_%s\n", $1, substr($0, index($0, $2))); }'
echo "62_02_x.png" | awk -F_ '{ printf("%04d_%s\n", $1, substr($0, index($0, $2))); }'
cabad
  • 4,555
  • 1
  • 20
  • 33
2

Code for GNU :

sed -r ':k;s/\b[0-9]{1,3}_/0&/g;tk'

Examples:

$ echo 6_02.png| sed -r ':k;s/\b[0-9]{1,3}_/0&/g;tk'
0006_02.png

$ echo 62_02.png| sed -r ':k;s/\b[0-9]{1,3}_/0&/g;tk'
0062_02.png

$ echo 162_02.png| sed -r ':k;s/\b[0-9]{1,3}_/0&/g;tk'
0162_02.png

$ echo 1632_02.png| sed -r ':k;s/\b[0-9]{1,3}_/0&/g;tk'
1632_02.png

$ echo 16324_02.png| sed -r ':k;s/\b[0-9]{1,3}_/0&/g;tk'
16324_02.png
captcha
  • 3,756
  • 12
  • 21