extracting substrings from variables

Hello Everyone,

I am looking for a way to extract substrings to local variables. Here is the format of the string variable i am using :

/var/x/www && /usr/x/share/doc && /etc/x/logs

where the substrings i must extract are the "/var/x/www" and such.
I was originally thinking of using something like "awk" to extract each substring and place them in $1, $2.....$NF which would be perfect.
Does anyone have an idea?

Thanks a lot for your replies

try this

echo $string||awk 'BEGIN{FS="[&][&]"}{for(i=1;i<=NF;i++){print $i}}'
[ctsgnb@shell ~]$ set -- $(echo '/var/x/www && /usr/x/share/doc && /etc/x/logs' | sed 's/ &&//g')
[ctsgnb@shell ~]$ echo $1
/var/x/www
[ctsgnb@shell ~]$ echo $2
/usr/x/share/doc
[ctsgnb@shell ~]$ echo $3
/etc/x/logs
[ctsgnb@shell ~]$

Hi,

Thank you for your lightning quick reply !! :b:

I have typed a test script that goes like this :

#!/bin/bash


var='/var/x/www &&  /usr/x/share/doc &&  /etc/x/logs'

echo $var||awk 'BEGIN{FS="[&][&]"}{for(i=1;i<=NF;i++){print $i}}'

just to test you solution, yet the return is this :

/var/x/www && /usr/x/share/doc && /etc/x/logs

it seems like the awk does not recognise the && separation

use "nawk" or "/usr/xpg4/bin/awk" (the POSIX one) instead of the simple "awk" if you are running on SunOS/Solaris plateform

---------- Post updated at 11:03 AM ---------- Previous update was at 11:00 AM ----------

By the way, by using the && as field separator you may get unexpected heading and/or trailing space

thanks for the tip:b: but i use RedHat platform. here is the shell version :

GNU bash, version 3.1.17(1)-release (x86_64-redhat-linux-gnu)

remove the double pipe between echo and awk. Use only one pipe, it worked on removing it, though strange.

Great!! :b:

I have just tested it, it will work just fine, i will replace the print $i with my instructions then.

Thanks a lot for your help!!

You should remove the leading space

[ctsgnb@shell ~]$ echo $var |awk 'BEGIN{FS="[&][&]"}{for(i=1;i<=NF;i++){print $i}}'
/var/x/www
 /usr/x/share/doc
 /etc/x/logs
[ctsgnb@shell ~]$ echo $var |awk 'BEGIN{FS="[&][&]"}{gsub(" ","",$0);for(i=1;i<=NF;i++){print $i}}'
/var/x/www
/usr/x/share/doc
/etc/x/logs
[ctsgnb@shell ~]$

Any idea why this double pipe causing problem. I am bit confused with that.

double pipe means "OR"
cond1 || cond2
cond2 will be evaluated only if cond1 fails.

$ a=1
[ctsgnb@shell ~]$ [[ $a -eq 0 ]] && echo "OK" || echo "KO"
KO
[ctsgnb@shell ~]$ a=0
[ctsgnb@shell ~]$ [[ $a -eq 0 ]] && echo "OK" || echo "KO"
OK
double pipe means "OR"

I am so lost here. I was think something is mystery using unix pipes ... I was totally out of context

sorry to reopen this post.....:rolleyes:

thanks to your solutions things got better but i am having a hard time integrating a command that normally works into the awk "loop" :

echo $NEW_PATH|awk 'BEGIN{FS="[&][&]"}{for(i=1;i<=NF;i++) find $i -mtime +$RET -exec rm {} \;}'

returns the following error :

awk: BEGIN{FS="[&][&]"}{for(i=1;i<=NF;i++) find $i -mtime +$RET -exec rm {} \;}
awk:                                                                     ^ syntax error
awk: BEGIN{FS="[&][&]"}{for(i=1;i<=NF;i++) find $i -mtime +$RET -exec rm {} \;}
awk:                                                                        ^ backslash not last character on line

I dont undestand this last character issue.....:wall:

Do you have control over the field separator character? If you used a more common separator like a pipe (or converted " && " to a pipe before processing it) you could parse the string and put the values into an array (I am using ksh93 on Solaris by the way):

#!/usr/dt/bin/dtksh

# Set a string variable.
pathlist="/var/x/www|/usr/x/share/doc|/etc/x/logs"

# Set the Input Field Separator. 
IFS='|'

# Create an array, with elements automatically parsed by the IFS string.
set -A parsed_pathlist_array $pathlist

# Prove it works.
print "1: ${parsed_pathlist_array[0]}"
print "2: ${parsed_pathlist_array[1]}"
print "3: ${parsed_pathlist_array[2]}"

exit 0

Just another way to go about it.

Gary

Thanks for the idea Gary :b:

However the interesting part of "awk" is that the number of strings in the variable changes from line to line, thus the $NF token in awk is really useful there

---------- Post updated at 06:21 PM ---------- Previous update was at 04:35 PM ----------

@Gary : scratch my last post

My remark was dumb, i can use a while loop to reach the end of the array so your post is dead accurate.

I have been able to change the "PATH" variable to something like this:

path1|path2|path3

But i come across this error:

./test.sh: line 40: set: -A: invalid option
set: usage: set [--abefhkmnptuvxBCHP] [-o option] [arg ...]

:wall:

My example works with ksh93 on solaris. You will have to do some searching to see if you can do the equivalent on your system and shell.

P.S. For looping, the syntax to get the number of entries in the array is:

${#arrayname
[*]}

which would allow for dynamically looping through the array. Modified example:

#!/usr/dt/bin/dtksh

# Set a string variable.
pathlist="/var/x/www|/usr/x/share/doc|/etc/x/logs"
integer ctr=0
integer nbr_elements

# Set the Input Field Separator.
IFS='|'

# Create an array, with elements automatically parsed by the IFS string.
set -A parsed_pathlist_array $pathlist
nbr_elements=${#parsed_pathlist_array
[*]}

# Prove it works.  Loop through the array.
while (( $ctr < $nbr_elements ))
do
  print "array element $ctr: ${parsed_pathlist_array[$ctr]}"
  ((ctr+=1))
done

exit 0

I'm not a bash guy, but I played around for the fun of it and this works to parse a string:

#!/bin/bash

# Set a string variable.
pathlist="/var/x/www|/usr/x/share/doc|/etc/x/logs"
ctr=0

# Set the Input Field Separator.
IFS='|'

# Prove it works.  Loop
for element in $pathlist
do
  echo "substring element $ctr: $element"
  ctr=`expr $ctr + 1`
done

exit 0