0

I have a variable in my shell script that looks like this:

DIR="HOME_X_Y_Z";

It represents a directory name. Imagine I have multiple directories all named something like this:

HOME_1_2_Z/
HOME_9_A_Z/
HOME_3_5_Z/
etc...

The only values that change are those located at position X and Y. Is there a regular expression I could use (maybe with sed or awk) to peel those values out? I want to be able to used them independently elsewhere in my script.

So I would be able have 2 more variables:

X_VALUE="";
Y_VALUE=""; 

Thanks

3 Answers 3

4

Set IFS and use read:

IFS=_ read home x y z rest <<< 'HOME_X_Y_Z'
echo "$y" # "Y"
echo "$z" # "Z"
echo "$x" # "X"
Sign up to request clarification or add additional context in comments.

2 Comments

That is a great answer as well, but some people might freak out about home part. Also, you have forgot to quote your variable and place a $ mark as well. It must be <<< "$HOME_X_Y_Z" and echo "$y"
@Aleks-DanielJakimenko Well, the input is supposed to be a literal string, but you're right about the rest. Thanks! Fixed.
1

This is very easy with pure bash:

IFS='_' read X_VALUE Y_VALUE Z_VALUE <<< "${DIR#*_}"

Explanation:
So, ${DIR#*_} is going to remove the shortest match from the beggining of the string. See parameter expansion cheat sheet for more stuff like that.

echo ${DIR#*_} # returns X_Y_Z

After that all we have to do is change the default IFS to _ and read our values.

4 Comments

I can mark this as answered in 6 minutes, job done though. Cheers buddy!
# removes the shortest match, not the longest.
It would be simpler to discard the prefix with a dummy variable, i.e., IFS=_ read _ X_VALUE Y_VALUE Z_VALUE <<< "$DIR".
that's what I meant, Thanks! @chepner yeah, that's why there are several answers :)
1

If you don't want to fiddle with IFS you can still do it in pure Bash by stripping off the parts you don't want, but it's not a one-liner:

DIR2=${DIR#HOME_}
DIR2=${DIR2%_Z}      # $DIR now contains just X_Y
X_VALUE=${DIR2%_*}
Y_VALUE=${DIR2#*_}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.