LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
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.

Notices


Reply
  Search this Thread
Old 04-26-2013, 05:22 PM   #1
Kustom42
Senior Member
 
Registered: Mar 2012
Distribution: Red Hat
Posts: 1,604

Rep: Reputation: 415Reputation: 415Reputation: 415Reputation: 415Reputation: 415
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.
 
Old 04-26-2013, 05:30 PM   #2
Kustom42
Senior Member
 
Registered: Mar 2012
Distribution: Red Hat
Posts: 1,604

Original Poster
Rep: Reputation: 415Reputation: 415Reputation: 415Reputation: 415Reputation: 415
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.
 
Old 04-26-2013, 09:30 PM   #3
catkin
LQ 5k Club
 
Registered: Dec 2008
Location: Tamil Nadu, India
Distribution: Debian
Posts: 8,578
Blog Entries: 31

Rep: Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208Reputation: 1208
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.
 
2 members found this post helpful.
Old 04-27-2013, 01:35 AM   #4
Toggan
Member
 
Registered: Oct 2011
Distribution: CentOS 5.9
Posts: 39

Rep: Reputation: 6
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
 
1 members found this post helpful.
Old 04-29-2013, 10:16 AM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

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

Last edited by David the H.; 05-05-2013 at 07:34 AM. Reason: code fix
 
1 members found this post helpful.
Old 04-29-2013, 05:08 PM   #6
Kustom42
Senior Member
 
Registered: Mar 2012
Distribution: Red Hat
Posts: 1,604

Original Poster
Rep: Reputation: 415Reputation: 415Reputation: 415Reputation: 415Reputation: 415
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.
 
Old 05-05-2013, 07:33 AM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

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


Reply


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
Bash shell script with for loop question? beaven67 Programming 6 10-05-2012 09:57 AM
[SOLVED] BASH scripting Question - Select loop displaying output StaffSergeant Programming 25 11-22-2011 05:19 PM
Bash Script Loop Question SoulShaker Linux - Server 5 06-17-2009 01:44 PM
Bash script Question while loop glennph93 Programming 6 05-25-2007 03:27 PM
bash script - for loop question rignes Programming 3 10-05-2004 11:16 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:51 PM.

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