Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

All,

I have file names that will be always in the following format "rX_Q_Y_filename.mp3" where X and Y are numbers (0-9). FYI, X and Y in the filename can be 1 or more digits

example "r1234_Q_456789_filename.mp3"

How do I extract the 'Q_456789" part of the file name using bash script?

share|improve this question
    
Why not use Perl? It's way easier: $your_string =~ /r.+_(Q_\d+)_filename\.mp3/; print $1; – m0skit0 Oct 7 '11 at 8:18

For bash:

# See "modern regexps" in regex(7) for regexp syntax.

# The intermediate $re variable is not necessary, but it removes the
# need for having to escape every single metacharacter in the regexp.

re='_(Q_[[:digit:]]+)'

if [[ $name =~ $re ]]; then
    part=${BASH_REMATCH[1]}
    echo "Matched on $part"
else
    echo "Match failed"
fi
share|improve this answer

I am not sure if this is exactly what you are after, but:

ls -1 r*.mp3 | egrep -o Q_[0-9]+

will return a list of Q_{numbers}

$ ls r*.mp3
r1234_Q_456789_test.mp3

$ ls -1 r*.mp3 | egrep -o Q_[0-9]+
Q_456789
share|improve this answer

Here's an inefficient way of doing it with awk.

$ ls -1 *.mp3
r1234_Q_433_filename.mp3
r1234_Q_456789_filename.mp3
r323_Q_433_filename.mp3

$ ls -1 *.mp3 | awk '{print substr($1, match($0, /Q/), (match($0, /\_f/) - match($0, /Q/)))}'
Q_433
Q_456789
Q_433
share|improve this answer

Sed oneliner:

sed 's/[^Q]*\(Q_[0-9]*\)_.*/\1/' <<<"r1234_Q_456789_filename.mp3"
Q_456789

'Q' is the first character your interested in so throw away everything before it, group the 'Q_number' and then trash the rest, substitute the back-reference.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .