LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Inspected a character on a particular position in a word (https://www.linuxquestions.org/questions/programming-9/inspected-a-character-on-a-particular-position-in-a-word-653202/)

kushalkoolwal 07-02-2008 07:20 PM

Inspected a character on a particular position in a word
 
I have a variable in my shell script, say $DEVICE, which contains the following string:
Code:

/dev/scd0
Now here the letter '0' could be anything like:
Code:

"0" in /dev/scd0
"1" in /dev/scd1
"2" in /dev/scd2
and so on...


Now I would like to inspect which letter is there after the string /dev/scd?

So for example what is there at the position "*" in the string /dev/scd*

Thanks

Mr. C. 07-02-2008 07:40 PM

echo $DEVICE | sed 's-^/dev/scd--'

will strip all but the trailing device number. Assign that to a variable:

DEVNO=$(echo $DEVICE | sed 's-^/dev/scd--')

You can also use shell variable string manipulation as well, but the above is easier perhaps for you to initially understand.

chrism01 07-02-2008 07:51 PM

dev=/dev/scd2
echo $dev|cut -c9
2

Mr. C. 07-02-2008 08:06 PM

Or perhaps better yet:

Code:

echo /dev/scd26 | perl -lne 'print $1 if /(\d+)$/'
26

in case the device has more than 9 units.

ntubski 07-02-2008 08:58 PM

I think in this case shell variable string manipulation is pretty clear (assuming bash):
Code:

~/tmp$ echo $DEVICE
/dev/scd26
~/tmp$ echo ${DEVICE#/dev/scd}
26


Mr. C. 07-02-2008 09:23 PM

The problem I personally have with parameter expansion for variables is that it is generally limited and certainly non-intuitive for new users. And once you need slightly more complex patterns, it becomes unwieldy. It uses only a limited form of filename patterns, and doesn't behave as one might expect:

Code:

$ DISK=/dev/sda22
$ echo ${DISK#/dev/*a}
22
$ echo ${DISK#/dev/[a-z]}            # OK, a-z char range matches
da22
$ echo ${DISK#/dev/[a-z]*}            # What!  Ok, maybe longer form...
da22
$ echo ${DISK##/dev/[a-z]*}          # Hmmm, that's not what I want either

$ echo ${DISK#/dev/[a-z][a-z][a-z]}  # Good, but forces 3 chars in pattern
22
$ echo ${DISK#/dev/[a-z][a-z][a-z]*}  # What!  Same as above.
22
$ echo ${DISK##/dev/[a-z][a-z][a-z]*} # Nope.  How do I say "all but last n digits" ?

$

And more complex patterns are even more heinous.

andymalato 07-02-2008 09:29 PM

Code:

echo $DEVICE
/dev/sda2
echo ${DEVICE:8:4}
2


Mr. C. 07-02-2008 09:46 PM

... but I think one shouldn't have to think hard, worrying about searching the code for finding various oddities like :8:4, which are very specific to only certain devices types. For example, the solution offered doesn't work for devices with varying pattern lengths. Assume we want to find the unit number for either raidNN or sdaNN:

Code:

$ DISK=/dev/raid20
$ echo ${DISK:8:4}  # Oops, won't work.
d20


Kenhelm 07-03-2008 04:25 PM

Two more methods:
To return only the part of the line which matches the search pattern:-
Code:

echo /dev/raid20 | grep -o '[0-9]*$'
20

To delete the unwanted characters:-
Code:

echo /dev/raid20 | tr -d '[:alpha:][:punct:]'
20

(but used on '/dev/fd0d360' this outputs '0360' which may or may not be what is wanted.)

Mr. C. 07-03-2008 04:53 PM

Who says computer people are not creative!? :-)

Good stuff all.

ghostdog74 07-03-2008 08:37 PM

Code:

# DEVICE=/dev/scd1
# expr "$DEVICE" : '.*scd\(.\)'
1



All times are GMT -5. The time now is 07:42 AM.