开发者

String Manipulation in Bash

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

I have the following file among other files i开发者_Go百科n my directory:

jdk-6u20-solaris-i586.sh

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?


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:

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

Flavour according to taste.


Using only Bash:

for file in jdk*i586*
do
    file="${file%*-solaris*}"
    file="${file/-/1.}"
    file="${file/u/.0_}"
    do_something_with "$file"
done


i think that

sed
is the command for you


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"
    fi
done


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.


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/'`


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//'`
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜