LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Bash_rematch (https://www.linuxquestions.org/questions/programming-9/bash_rematch-945917/)

casperdaghost 05-19-2012 02:55 PM

Bash_rematch
 
THe below is a java executalbe - If i execute it from the commnad line, without todays session
it strikes a error.
Code:

casper ~ $ /data/execCommand ntf2201.1 /SPINMASTER/RELEASEALLEQUITIES
ERROR: Must specify the active session: 000005947S
casper ~ $ /data/execCommand ntf2201.1 /SPINMASTER/RELEASEALLEQUITIES 000005947S
Done: RELEASEALLEQUITIES

SO i made this script - which works fine:
Code:

#!/bin/bash
for i in $(grep -i masterexecutor /casper/*commands| perl -nle 'print /(server\d+\.?\d+)/' |sort -u)
        do
        output=$(/data/execCmd $i /SPINMASTER/RELEASEALLEQUITIES | cut -d" " -f7)
        if [[ -n $output ]] ; then  # -n tests to see id the argument is not empty
                echo "/data/execCommand $i /SPINMASTER/RELEASEALLEQUITIES $output"
                /data/execCommand $i /SPINMASTER/RELEASEALLEQUITIES $output
        fi

done

which works fine - However using cut -d is boring.

I was looking into using the BASH_REMATCH - but it does not like the perl like regex \d{9}\w
and when I use the postix, it does not seem to like that either.
Anybody know of a good reference for the BASH_REMATCH?
Can I parse/capture strings with BASH_REMATCH?
Code:

#!/bin/bash
for i in $(grep -i masterexecutpor /var/ftp/*commands| perl -nle 'print /(server\d+\.?\d+)/' |sort -u)
        do
        output=$(/data/execCmd $i /SPINMASTER/RELEASEALLEQUITIES)
        if [[ -n $output ]] ; then  # -n tests to see id the argument is not empty
                if [[ $output =~ ([[:digit:]]*[[:alpha:]]) ]]; then
                /data/execCmd $i /SPINMASTER/RELEASEALLEQUITIES "${BASH_REMATCH[1]}"
                fi
        fi
done


Nominal Animal 05-19-2012 03:35 PM

Why not use
Code:

output="${output//[$'\t\n\v\f\r ']/}"
output="${output##*:}"
LANG=C LC_ALL=C
if [ ${#output} -ge 2 -a "$output" = "${output//[^0-9]/}${output//[^A-Za-z]/}" ]; then

instead?

The first line removes all whitespace from output.

The second line removes everything up to and including the final colon from output. This should leave just the identifier in output.

The test checks if output is at least two characters long, and contains digits 0-9 followed by letters A-Z or a-z (either may be omitted). In an UTF-8 locale, [A-Za-z] glob pattern may contain non-ASCII letters (although I think Bash has some bugs here currently). Explicitly setting the locale to POSIX will make sure that does not happen. In fact, you might wish to set the locale at the start of your script, and be done with it.

It sure is ugly, though.

After a second look, I think I'd personally use
Code:

LC_ALL=C LANG=C
output=$(/data/execCmd "$i" /SPINMASTER/RELEASEALLEQUITIES | sed -ne 's|^ERROR.*session: *\([0-9]\+[A-Za-z]*\) *\r*$|\1|p)
if [ -n "$output" ]; then
    echo "/data/execCommand "$i" /SPINMASTER/RELEASEALLEQUITIES $output"
    /data/execCommand "$i" /SPINMASTER/RELEASEALLEQUITIES $output
fi

instead. The sed command replaces the cut, while also making sure the line it uses is correctly formatted, and the identifier itself is acceptable. If not, it outputs nothing.
Note that if there were more than one "ERROR...session:" in the first output, they would all be listed as separate parameters to the command.

lej 05-19-2012 03:52 PM

OK, I've been up for about 20 hours, so maybe I'm missing something, but AFAICT, you just want the final word from the output, right? If so, why not assign it to array and yank out the final word.

Code:

output=($(/data/execCmd $i /SPINMASTER/RELEASEALLEQUITIES))
output=${output[${#output}-1]}

Or just use awk:

Code:

output=$(/data/execCmd $i /SPINMASTER/RELEASEALLEQUITIES | awk '{print $NF}')

grail 05-20-2012 09:25 AM

When using exotic items, ie not just straight numbers and letters, i find it is best to store the regex in a variable, so something like the following should work:
Code:

#!/bin/bash

regex=' [[:digit:]]{9}[[:alpha:]]$'

for i in $(grep -i masterexecutpor /var/ftp/*commands| perl -nle 'print /(server\d+\.?\d+)/' |sort -u)
do
    [[ $(/data/execCmd $i /SPINMASTER/RELEASEALLEQUITIES) =~ $regex ]] && /data/execCmd $i /SPINMASTER/RELEASEALLEQUITIES "${BASH_REMATCH[0]}"
done

Untested but you get the idea :)


All times are GMT -5. The time now is 02:36 PM.