LinuxAnswers - the LQ Linux tutorial section.
Go Back > Forums > Non-*NIX Forums > Programming
User Name
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.


  Search this Thread
Old 07-02-2008, 07:20 PM   #1
Senior Member
Registered: Feb 2004
Location: Middle of nowhere
Distribution: Debian Squeeze
Posts: 1,249

Rep: Reputation: 48
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:
Now here the letter '0' could be anything like:
"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*

Old 07-02-2008, 07:40 PM   #2
Mr. C.
Senior Member
Registered: Jun 2008
Posts: 2,529

Rep: Reputation: 61
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.
Old 07-02-2008, 07:51 PM   #3
LQ Guru
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.7, Centos 5.10
Posts: 17,051

Rep: Reputation: 2261Reputation: 2261Reputation: 2261Reputation: 2261Reputation: 2261Reputation: 2261Reputation: 2261Reputation: 2261Reputation: 2261Reputation: 2261Reputation: 2261
echo $dev|cut -c9
Old 07-02-2008, 08:06 PM   #4
Mr. C.
Senior Member
Registered: Jun 2008
Posts: 2,529

Rep: Reputation: 61
Or perhaps better yet:

echo /dev/scd26 | perl -lne 'print $1 if /(\d+)$/'
in case the device has more than 9 units.
Old 07-02-2008, 08:58 PM   #5
Senior Member
Registered: Nov 2005
Distribution: Arch
Posts: 2,893

Rep: Reputation: 1084Reputation: 1084Reputation: 1084Reputation: 1084Reputation: 1084Reputation: 1084Reputation: 1084Reputation: 1084
I think in this case shell variable string manipulation is pretty clear (assuming bash):
~/tmp$ echo $DEVICE
~/tmp$ echo ${DEVICE#/dev/scd}
Old 07-02-2008, 09:23 PM   #6
Mr. C.
Senior Member
Registered: Jun 2008
Posts: 2,529

Rep: Reputation: 61
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:

$ DISK=/dev/sda22
$ echo ${DISK#/dev/*a}
$ echo ${DISK#/dev/[a-z]}             # OK, a-z char range matches
$ echo ${DISK#/dev/[a-z]*}            # What!  Ok, maybe longer form...
$ 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
$ echo ${DISK#/dev/[a-z][a-z][a-z]*}  # What!  Same as above.
$ 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.
Old 07-02-2008, 09:29 PM   #7
LQ Newbie
Registered: Jun 2006
Distribution: Red Hat, Solaris, FreeBSD
Posts: 20

Rep: Reputation: 0
echo $DEVICE
echo ${DEVICE:8:4}
Old 07-02-2008, 09:46 PM   #8
Mr. C.
Senior Member
Registered: Jun 2008
Posts: 2,529

Rep: Reputation: 61
... 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:

$ DISK=/dev/raid20
$ echo ${DISK:8:4}   # Oops, won't work.
Old 07-03-2008, 04:25 PM   #9
Registered: Mar 2008
Location: N. W. England
Distribution: Mandriva
Posts: 333

Rep: Reputation: 141Reputation: 141
Two more methods:
To return only the part of the line which matches the search pattern:-
echo /dev/raid20 | grep -o '[0-9]*$'
To delete the unwanted characters:-
echo /dev/raid20 | tr -d '[:alpha:][:punct:]'
(but used on '/dev/fd0d360' this outputs '0360' which may or may not be what is wanted.)
Old 07-03-2008, 04:53 PM   #10
Mr. C.
Senior Member
Registered: Jun 2008
Posts: 2,529

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

Good stuff all.
Old 07-03-2008, 08:37 PM   #11
Senior Member
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

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


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] find a word in a file, and change a word beneath it ?? vikas027 Programming 10 02-14-2008 09:46 PM
find a string followed by any word character in bash bryan.out.there Programming 2 07-12-2006 06:36 AM
about wide character and multiple byte character George2 Programming 5 05-23-2006 01:03 AM
Java: Change first character in word to upper AMMullan Programming 4 04-05-2004 03:16 PM
function won ' t return character array word Linh Programming 1 07-31-2003 06:11 PM

All times are GMT -5. The time now is 08:10 AM.

Main Menu
Write for LQ is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration