ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
What I would like to do is read each line in the atdinfile:
A sample atdinfile would look like this:
651
652
653
654
655
656
657
658
659
660
661
664
665
666
667
668
I would like to grep through each atd job id looking for a match based on the input from another infile would is a listed of user groups:
A sample grplist file would look like this;
groupa
groupb
groupc
groupd
groupe
The code below will go through the list of atd jobs only once and try to match a corresponding line in the group file. This is not what I want. I want to grep for every group in each atd line before it moves onto the next atd job. Another problem is that the atd job list could be any number of lines whereas the grplist will tend to be static.
Code:
#!/bin/bash
set -x
ATDINFILE=/root/atdoutter.txt
DELTIMER=/root/delist.txt
USERNAME=ttimer
/usr/bin/atq | awk '{print $1}'|sort > $ATDINFILE
GRPLIST=/root/grouplist.txt
exec 3<$ATDINFILE
exec 4<$GRPLIST
while read atd <&3 && read grp <&4
do
at -c $atd|grep -wq "tmp-lock-ou.ldif."$USERNAME"" && at -c $atd | grep -wq "$grp"
if [ $? -eq 0 ] ; then
echo -e "${bldgrn}A $grp lock timer has been found for $USERNAME ${txtrst}" && echo "timer found for $USERNAME"
sleep 1.5
echo " "
echo $atd | tee -a $DELTIMER >/dev/null 2>&1
sleep 2
fi
done < $ATDINFILE
Help us to help you. Provide two sample input files (10-15 lines will do). Construct a sample output file which corresponds to your sample inputs and post the samples here. With "Before and After" examples we can better understand your needs and also judge if our proposed solution fills those needs.
Help us to help you. Provide two sample input files (10-15 lines will do). Construct a sample output file which corresponds to your sample inputs and post the samples here. With "Before and After" examples we can better understand your needs and also judge if our proposed solution fills those needs.
Daniel B. Martin
Daniel, thanks for your response. I'm looking to act on the each line in the files as I'm not really trying to construct a third output.
Ultimately I want to be able to run the atd command to list each atd job and then grep for each group inside of that job and perform another action if the exit status is 0.
For example using the atd job 651.
at -c 651 |grep groupa
if { $? -eq 0 ] ; then
do something
fi
at -c 651 |grep groupb
if { $? -eq 0 ] ; then
do something
fi
and so on and so on until each job id has been searched for each group.
Ultimately I want to be able to run the atd command to list each atd job and then grep for each group inside of that job and perform another action if the exit status is 0.
Perhaps you want to use nested loops. The outer loop would run through every element in Input File A and the inner loop would run through every element in Input File B.
cat $InFile1 | # Supply input from InFile1.
while read IF1value # As long as there is another line to read ...
do
cat $InFile2 | # Supply input from InFile2.
while read IF2value # Read one value at a time.
do
let "product=$IF1value*$IF2value"
echo $IF1value "times" $IF2value "equals" $product
done
done >$OutFile
... produced this OutFile ...
Code:
1 times 4 equals 4
1 times 5 equals 5
1 times 6 equals 6
2 times 4 equals 8
2 times 5 equals 10
2 times 6 equals 12
3 times 4 equals 12
3 times 5 equals 15
3 times 6 equals 18
First, the usual note of USE MORE QUOTES. Any unquoted expansion smells bad and can easily bite you down the road. One of the most important skills in bash is to have an instinctive wrongness reaction to unquoted expansions.
On the topic of the actual issue of nesting while-read loops, you can something like "5< file" to redirect the file into FD 5, and then use "read -u 5" to pull from that FD. This technique cuts out the Useless Use Of Cat.
Don't use ABS as a resource. It teaches bad style all over the place, and is only somewhat useful if you already know enough about bash to not really need it. http://mywiki.wooledge.org/BashGuide is far far better.
First, the usual note of USE MORE QUOTES. ...
On the topic of the actual issue of nesting while-read loops ...
... ABS ... is only somewhat useful if you already know enough about bash ...
Thank you for the suggestions and pointers. I have little bash experience and that's the reason I had to "borrow" code from a web page prompted by a Google search.
In an earlier post I suggested nested do-loops, and the clumsy code in the follow-up post was an attempt to show the OP what nested do-loops look like.
It would be instructive if you reworked the code to show how it should be done. I hope you will do that.
while read atdout; do
while read accessgrp; do
at -c $atdout | grep -wq "tmp-lock-ou.ldif."$USERNAME"" && at -c $atdout | grep -wq "$accessgrp"
if [ $? -eq 0 ] ; then
echo -e "${bldgrn}A $accessgrp lock timer has been found for $USERNAME ${txtrst}" && echo "Timer found for $USERNAME" > $TIMEROUT
sleep 1.5
echo " "
echo -e "${bldylw}Displaying the current timer... ${txtrst}" && atq | grep $atdout | sed 's/^....//' |sed 's/......$//' | tee $LOCKTIME
sleep 3
echo " "
echo -e "${bldylw}Would you like to set a new timer for $USERNAME (yes/no)? ${txtrst}"
read input </dev/tty
if [[ $input = "yes" || $input = "YES" || $input = "y" || $input = "Y" ]]; then
echo $atdout | tee -a $DELTIMER >/dev/null 2>&1
do=enchilada
removetimer
elif [[ $input = "no" || $input = "NO" || $input = "n" || $input = "N" ]]; then
echo -e "${bldylw}Keeping old timer for $USERNAME ${txtrst}"
do=appetizer
else echo -e "${bldred}You entered an invalid option!${txtrst}"
cleanup
fi
fi
done < $GRPLIST
done < $ATDINFILE
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.