The for loop extracts the each line of the file so that at any one point, the value of i is
val1:env1:opt1
etc...
I would like to extract each individual attribute and pass it to a while loop as follows:
for i in $( cat refire.cfg | tail +$START | head -$STOP | grep -v "^#" | grep ':' )
do
# read the value of i here and break it down as arguments x y z for this loop
while read x y z
do
stuff
done
done
I want to be able to repeat the while loop for each iteration of i
I understand from your code what you're trying to read the i/p file in the while loop. I actually want to read the value of the variable i from the for loop.
When i try to make the while loop from $i , i am getting the following error :
Any thoughts?
---------- Post updated at 03:49 PM ---------- Previous update was at 03:27 PM ----------
Is there any way that the value of the variable i be stored in a file or a variable that can be read by the while loop.
I have tried writing to a file and it does not work.
for i in $( cat rparam.cfg | tail +$RESPONSE | head -$RESPONSESTOP | grep -v "^#" | grep ':' )
echo $i
$i > .tempparam
while read x y z
do
<stuff>
done < tempparam
rm -f tempparam
done
Maybe you post a snippet of that refire.cfg or now called rparam.cfg so we can provide some more direct code. The grep'ing might not be needed to supply a for loop when being used directly on that file.
In your original example the variable i was assigned the whole record (e.g. val1:env1:opt1 ). In the code that zaxxon suggested, the components val1 env1 opt1 were broken out and assigned to variables A, B and C. There would be no need to reference i, as there wasn't anything assigned to i anyway. You should be able to use A, B, and C as is.
From your original post, you also do a lot of extra work to only read a subset of lines from the input file. That isn't handled by zaxxon's example. Moving along the same lines as was offered, the following code will generate just the lines between START and STOP (inclusive) and assign them to the variables f1, f2, and f3 (A, B, C).
awk -F : -v last=${STOP:-0} -v first=${START:-0} '
/^#/ { next; }
NR >= first && (last == 0 || NR <= last) {
print $1, $2, $3, $0
}
' input-file | while read f1 f2 f3 i
do
echo "first field: $f1"
echo "second field $f2"
echo "third field $f3"
echo "whole record (i) $i"
done
Thanks Agama. Having tried the code above, i am getting an EOF error. Can you please explain what the awk is doing and if the format of the code is correct? I am getting the following error
---------- Post updated at 06:48 PM ---------- Previous update was at 05:36 PM ----------
Hi Agama,
I am unfamiliar with the syntax of the belwo code that you provided. I am getting an error from the code. Can you please let me know if the format of the code is correct? Thanks in advance.
awk -F : -v last=${STOP:-0} -v first=${START:-0} '
/^#/ { next; }
NR >= first && (last == 0 || NR <= last) {
print $1, $2, $3, $0
}
' input-file | while read f1 f2 f3 i
do
I cut/pasted the code in your post and it seems fine to me; I'm not getting an error. Can you past in your whole script, there is likely a typo somewhere in it.
An explanation:
The STOP and START shell variables allow you to define a line range from the input file. If not defined, the whole file is processed. If only START is defined, all lines before START are skipped. If STOP is defined, all lines after that line are skipped.
awk -F : -v last=${STOP:-0} -v first=${START:-0} '
/^#/ { next; } # if a line in the input starts with a hash, it is skipped
# this section prints the first three fields and the whole line
# the $0 prints the whole line with the separators and is needed only to
# show that as $1 in the shell script echo
NR >= first && (last == 0 || NR <= last) {
print $1, $2, $3, $0
}
' input-file
Thanks a mil for the explanation. It's gonna be pretty handy.
I use the same code that you've posted and get the EOF error. My frustrations not withstanding, i have gone ahead and written the results of the for loop into a tempfile and then proceeded to read the code from below(i have the working section commented out). I'd still like to understand why the below code throws up an error. I am only new to shell script and i'd like to understand whats going on so as not to repeat the errors. Thank you for your time
for i in $( cat param.txt | tail +$START | head -$STOP | grep -v "^#" | grep ':' )
do
#echo $i
# printf "%s\n" "$i" >> .param
#printf "Press [enter] key to continue. . ."
#read enterKey
OLDIFS=$IFS
IFS=":"
awk -F : -v last=${RESPONSESTOP:-0} -v first=${RESPONSE:-0} '
/^#/ { next; }
NR >= first && (last == 0 || NR <= last) {
print $1, $2, $3, $0
}
' param.txt | while read x y z i
do
echo "first field $x"
echo "second field $y"
echo "third field $z"
echo "whole record (i) $i
done
#while read x y z
#do
#if [ "$z" == "GOD" ] ; then
# function1 $x $y
# function2 $y
# function3 $y
#fi
#if [ "$z" == "DEVIL" ] ; then
# function4
# fi
# done < .param
IFS=$OLDIFS
done
# echo "`cat .param`"
#rm -rf .param
You had a missing quote on one of the echo statements.
I think this is all that you need. The cat.... statement isn't necessary. Awk reads the param.txt file and thus you don't need to cat it through head/tail to get it into the awk.
awk -F : -v last=${RESPONSESTOP:-0} -v first=${RESPONSE:-0} '
/^#/ { next; }
NR >= first && (last == 0 || NR <= last) {
print $1, $2, $3, $0
}
' param.txt | while read x y z i
do
echo "first field $x"
echo "second field $y"
echo "third field $z"
echo "whole record (i) $i" # <missing close quote was here
if [[ $z == "GOD" ]]
then
function1 $x $y
function2 $y
function3 $y
fi
if [[ $z == "DEVIL" ]]
then
function4
fi
done
Or alternatively, use plain shell without pipes, e.g.
START=2; STOP=7
linenr=0
while IFS=: read x y z ; do
linenr=$((linenr+1));
[ $linenr -ge $START ] || continue
[ $linenr -le $STOP ] || break
case $x in
\#*) continue
esac
echo " Do your stufff with $x $y and $z at $linenr"
done < infile
Do your stufff with RED value2 and Y at 2
Do your stufff with BLUE value4 and Y at 4
Do your stufff with RED value5 and Y at 5
Do your stufff with RED value6 and Y at 6
Do your stufff with BLUE value7 and Y at 7
I have rectified the missing quote. when i run the script, i get the following error
---------- Post updated at 07:40 AM ---------- Previous update was at 07:26 AM ----------
In the above code, if i change the values of start and stop to 7 and 18 respectively and try to execute
echo " Do your stufff with $x $y and $z at $linenr"
i am not getting any output. I can only print the values between 1 and 6. If i try to print from 6 onwards, there is no output (I have over 50 files btw).
Hi, I just tried it and it works here. Could you post a representative sample of say 25 lines of the file you tested with? What shell/OS are you using?
I am using a file with the format given below. If i choose any value from 1-5 as start and end at say 15, your logic works. But if i choose say 7-13 , then the
Hi, what does echo $SHELL give? What shebang are you using in your script? On Solaris /bin/sh is not a POSIX shell, you should use /usr/xpg4/bin/sh instead or use bash.
function function1{
...
}
function 2{
...
}
for i in $( cat param.cfg | grep -v "^#" | grep ':' )
do
printf "$n. $i \t"
n=`expr $n + 1`
done
echo Please enter START
read START
echo Please enter STOP
read STOP
STOP=`expr $STOP - $START + 1`
n=$START
for i in $( cat rparam.cfg | tail +$START | head -$STOP | grep -v "^#" | grep ':' )
do
echo "$n. $i"
n=`expr $n + 1`
done
OLDIFS=$IFS
IFS=":"
linenr=0
while IFS=: read x y z ; do
linenr=$((linenr+1));
[ $linenr -ge $RESPONSE ] || continue
[ $linenr -le $RESPONSESTOP ] || break
case $x in
\#*) continue
esac
function1
done < param.cfg
The functions above are standard and it doesnt interfere with the o/p of the while loop. The main part of the code is as above. I've removed all the formattin echo's thats not relevant to the logic
---------- Post updated at 01:22 PM ---------- Previous update was at 01:16 PM ----------
A sample output of the above shell for different options is: