Take the 2-minute tour ×

I am a newbie in Bash and I am doing some string manipulation.

I have the following file among other files in my directory:


I am doing the following to get jdk-6u20 in my script:

myvar=`ls -la | awk '{print $9}' | egrep "i586" | cut -c1-8`
echo $myvar

but now I want to convert jdk-6u20 to jdk1.6.0_20. I can't seem to figure out how to do it.

It must be as generic as possible. For example if I had jdk-6u25, I should be able to convert it at the same way to jdk1.6.0_25 so on and so forth

Any suggestions?

share|improve this question

7 Answers 7

Depending on exactly how generic you want it, and how standard your inputs will be, you can probably use AWK to do everything. By using FS="regexp" to specify field separators, you can break down the original string by whatever tokens make the most sense, and put them back together in whatever order using printf.

For example, assuming both dashes and the letter 'u' are only used to separate fields:

echo $myvar | awk 'BEGIN {FS="[-u]"}; {printf "%s1.%s.0_%s",$1,$2,$3}'

Flavour according to taste.

share|improve this answer

Using only Bash:

for file in jdk*i586*
    do_something_with "$file"
share|improve this answer

i think that

is the command for you

share|improve this answer

You can try this snippet:

for fname in *; do
    newname=`echo "$fname" | sed 's,^jdk-\([0-9]\)u\([0-9][0-9]*\)-.*$,jdk1.\1.0_\2,'`
    if [ "$fname" != "$newname" ]; then
        echo "old $fname, new $newname"
share|improve this answer
awk 'if(match($9,"i586")){gsub("jdk-6u20","jdk1.6.0_20");print $9;}'

The if(match()) supersedes the egrep bit if you want to use it. You could use substr($9,1,8) instead of cut as well.

share|improve this answer

garph0 has a good idea with sed; you could do

myvar=`ls jdk*i586.sh | sed 's/jdk-\([0-9]\)u\([0-9]\+\).\+$/jdk1.\1.0_\2/'`
share|improve this answer
yeah, I know what sed does, but not how to use it :) anyway this sample just assigns the original file name to myvar, in my test. –  garph0 May 22 '10 at 21:02
Odd, it works for me... maybe this is some difference between Solaris and Linux, now that I think about it. In that case try msw's answer (I would have edited mine to match if he hadn't posted) –  David Z May 22 '10 at 21:12
Hmm, I get the following when I apply your suggestion jdk-6u20-solaris-i586.sh –  kuti May 22 '10 at 21:37
Yeah, you mentioned that. I was saying that sed might work differently on Linux (which I use) vs. Solaris (which I assume you use), and that would account for the fact that this sed command works for me but not for you. msw has given you an alternate sed command that should work the same way on all platforms (Solaris and Linux). –  David Z May 22 '10 at 21:41

You're needing the awk in there is an artifact of the -l switch on ls. For pattern substitution on lines of text, sed is the long-time champion:

ls | sed -n '/^jdk/s/jdk-\([0-9][0-9]*\)u\([0-9][0-9]*\)$/jdk1.\1.0_\2/p'

This was written in "old-school" sed which should have greater portability across platforms. The expression says:

  • don't print lines unless they match -n
  • on lines beginning with 'jdk' do:
  • on a line that contains only "jdk-IntegerAuIntegerB"
    • change it to "jdk.1.IntegerA.0_IntegerB"
    • and print it

Your sample becomes even simpler as:

myvar=`echo *solaris-i586.sh | sed 's/-solaris-i586\.sh//'`
share|improve this answer
Might want to drop the p flag on that substitution, otherwise it prints twice (at least for me). –  David Z May 22 '10 at 21:40
aye, oops, edited, thanks. –  msw May 22 '10 at 21:44
And actually, come to think of it, the second substitution (the one I meant in the last comment) doesn't implement the transformation the OP wants. In the first one, you need to replace $ with .* to get it to work (since it should drop the -solaris-i586.sh from the end of the filename). –  David Z May 22 '10 at 21:45
This is perfect. Thank you msw & David. This worked with a little modification on Solaris 10: myvar=echo *solaris-i586.sh | sed "/^jdk/s/jdk-\([0-9][0 9]*\)u\([0-9][0-9]*\).*/jdk1.\1.0_\2/" echo $myvar Notice no -n & ' after sed.. –  kuti May 22 '10 at 22:04
I am trying to understand how sed works here. I can see that ^jdk represents the lines beginning with jdk. s for searching. How about [0-9][0-9] pieces? and why .*/jdk1.\1.0_\2/ part? I am sorry, I am just new to both sed and bash. I am assuming these are regular expressions? –  kuti May 22 '10 at 22:09

Your Answer


