0

I have a bash array containing several elements, only one of which will be in the format nn.wr , where nn is a variable integer.

eg

array=( "abcd" "01.wr" "ef_gh" )

However it could be anywhere in the array. How can I find it and return it? I was trying to use the partial match *.wr but can't quite get sed or awk to do it.

There must be a way!!

4

No need for external commands like sed or awk. Loop over the elements and use pattern matching:

#! /bin/bash
array=( "abcd" "01.wr" "ef_gh" )
unset found
for e in "${array[@]}" ; do
    if [[ $e == +([0-9]).wr ]] ; then
        found=$e
        break
    fi
done

[[ $found ]] && echo "$found"
3

You could switch to zsh which has builtin operators for that:

array=( "abcd" "01.wr" "ef_gh" xx.wr 99.wr )
  • first

    $ print -rC1 -- $array[(r)[0-9][0-9].wr]
    01.wr
    
  • last

    $ print -rC1 -- $array[(R)[0-9][0-9].wr]
    99.wr
    
  • index of first¹:

    $ print $array[(i)[0-9][0-9].wr]
    2
    
  • index of last²:

    $ print $array[(I)[0-9][0-9].wr]
    5
    
  • all

    $ print -rC1 -- ${(M)array:#[0-9][0-9].wr}
    01.wr
    99.wr
    

¹ If not found, that returns one more than the index of the last elememnt

² If not found, that returns 0

2

Provided your components don't contain a newline you can do something like this

array=( "abcd" "01.wr" "ef_gh" )
printf "%s\n" "${array[@]}" | grep -E '^[[:digit:]]+\.wr$'

Result

01.wr

If they do contain newlines you may be able to use grep's non-standard extensions

array=( "abcd" "01.wr" $'44.zz\n9.p' "ef_gh" )
printf "%s\0" "${array[@]}" | grep -Exz '[[:digit:]]+\.wr'

Result

01.wr

For a short array it would be more efficient to loop across it. For a large array using an external operator such as grep may well be faster.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.