LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Friday BASH Script question - Check output during for loop (https://www.linuxquestions.org/questions/programming-9/friday-bash-script-question-check-output-during-for-loop-4175459715/)

Kustom42 04-26-2013 05:22 PM

Friday BASH Script question - Check output during for loop
 
Hey folks,


It's been a long friday and was a late night last night so I'm pretty sure I'm just not thinking about this correctly but basically what I would like to do is check for a set of output while doing a for loop, break out of the loop if it contains a certain string of text.


So lets say I have a list of duplicates in a file /tmp/dupes.txt

Format:
Code:

client1
client2
client3
client4

Now lets say I do a

Code:


for dupe in $(/bin/cat /tmp/dupes.txt)
do
database query that provides text output
done

The query is a bit long and have ommitted as its not necssary but the output of the query comes in the following format:

Code:


                        name: client name;
            scheduled backup: Enabled;

Basically I want to only pull out the client names where the string for scheduled backup is == "Enabled" and discard output if it does not.

Is this easily achievable with my for loop setup or would I need to look at re-writing this a bit more robustly. Tried to nest an if statement in the for loop but wasnt able to get it to work.

Kustom42 04-26-2013 05:30 PM

Well I just went the lazy way here, logged all output to another tmp file, then do a grep on that for enabled. Not the most efficient but gets the job done. Will leave "unsolved" for a little while longer incase anyone has suggestions.

catkin 04-26-2013 09:30 PM

Something like (not tested)
Code:

for dupe in $(/bin/cat /tmp/dupes.txt)
do
  buf=$(database query using $dupe that provides text output)
  case $buf in
      *'scheduled backup: Enabled'* )
          do stuff
  esac 
done

You could use a regex instead of the case statement, something like [[ $buf =~ scheduled backup: Enabled ]] but it's a relatively recent feature and some regexes upset bash so the safe way is to put the regex in a variable ...
Code:

regex='scheduled backup: Enabled'
if [[ $buf =~ $regex ]]

... so it's not much cleaner than the more portable case statement anyway.

Toggan 04-27-2013 01:35 AM

You could throw an if statement in there to accomplish what you're looking for. While this isn't the most robust way of doing it, it should work:

Code:

for dupe in $(/bin/cat /tmp/dupes.txt); do
        var1=$(database query that provides text output)
        echo $var1 | grep -q Enabled
        if [[ $? -eq 0 ]]; then
                echo $var1 | grep name
        fi
done


David the H. 04-29-2013 10:16 AM

Please, don't ever use for loops with command substitutions, and especially not with cat.

Always use a while+read loop with text file or data stream input.

Otherwise, it's pretty much what Catkin said before.

Code:

#!/bin/bash

re='name: ([^;]+);.*scheduled backup: Enabled;'

while read -r query; do

    output=$( database query with "$query" )

    if [[ $output =~ $re ]]; then
        echo "${BASH_REMATCH[1]}"
    fi

done </tmp/dupes.txt

If you aren't using bash, then you'd have to change the built-in regex test to one or more grep/sed/awk commands or similar. But the basic process should be the same.

Another option, when you are in bash, is to use the mapfile built-in to populate an array with line entries. then you can safely use a for loop.

Code:

#!/bin/bash

re='name: ([^;]+);.*scheduled backup: Enabled;'

mapfile -t queries </tmp/dupes.txt

for query in "${queries[@]}"; do

    output=$( database query with "$query" )

    if [[ $output =~ $re ]]; then
        echo "${BASH_REMATCH[1]}"
    fi

done


Kustom42 04-29-2013 05:08 PM

David, in all my time with BASH nobody has ever mentioned the for loop reading gotchas that you have on that wiki post. Thank you for that especially. I re-scripted it today and it is a more scalable solution by far. Thanks to everyone for their input, my half-a$$ed script from last week is pretty sloppy.

David the H. 05-05-2013 07:33 AM

Glad to have helped out.

Yes, there's a lot of poor coding advice going around. While I've been scripting for almost 10 years now, it wasn't until I discovered the wooledge site a few years ago that I really learned what constitutes good and bad use of its features. I highly suggest reading through the BashGuide, BashFAQ, and BashPitfalls pages. It should help your coding immensely.


BTW, I notice I made a scripting mistake, capturing the query to the variable $output, but stupidly using the variable $text in the follow-up test. I'm updating the above to fix that.


All times are GMT -5. The time now is 07:25 PM.