Please use ***
[code][/code]*** tags around your code and data, to preserve the original formatting and to improve readability. Do
not use quote tags, bolding, colors, "start/end" lines, or other creative techniques.
Does this have to be a posix-compatible sh script, or can you use bash or another more advanced shell with features that can make things easier?
In any case, the first bit of advice I have is that
$(..) is highly recommended over `..`. This is a fully posix-compatible feature, so there's really no reason to ever use backticks anymore.
Second, formatting! Clean,
consistent formatting makes code readable and more easily debuggable. Be liberal with whitespace; indent all your sub-commands evenly, and separate logical sections with empty lines. Never just line everything up on the left edge. Add comments anywhere the code isn't completely obvious (and remember, what seems obvious to you now will not be so a year or so down the line).
One non-posix feature I would recommend is to use the
c-style for loop, instead of
seq.
If you simply want to read every line of the file, use a
while+read loop instead.
Code:
#!/bin/bash
start=1
step=1
end=50
datafile=/path/to/datafile.txt
for (( data=start ; data<=end ; data+=step )); do
r=$( gawk -v ln="$data" 'NR==ln { print $2 }' "$datafile" )
radius=$( echo "300 - $r" | bc )
echo "$radius"
done
Now a few more notes about the original script:
1)
Another option, instead of a
for loop, would be a
while loop:
Code:
data=$start
while (( data <= stop )); do #use [ "$data" -le "$stop" ] for posix compatibility
<commands>
data=$(( data + step ))
done
2)
It's not a good idea to hard-code filenames and similar data sources in a script.
Set it up in a variable at the top and use the variable in the code itself.
3)
Code:
line=`cat datafile | gawk -vcount="$data" 'NR=count {print}'`
as mentioned, in awk "=" sets a variable, "==" tests it.
Also notice the
Useless Use Of Cat.
Code:
line=$( gawk -vcount="$data" 'NR == count {print}' "$datafile" )
sed is easier to use when extracting lines anyway.
Code:
line=$( sed -n "${data} p" "$datafile" )
4)
Code:
r=`echo $line | gawk '{print $2}'`
If using bash, a
herestring can be used instead of
echo.
And
cut can usually be used instead of
awk for simple field extraction.
Code:
r=$( gawk '{print $2}' <<<"$line" )
r=$( cut -t ' ' -f2 <<<"$line" ) #assumes space-delimited fields
Built-in
parameter substitution may be even better.
(This example is a guess since I don't know what the line actually looks like,
but assuming space-delimited fields...)
Code:
r=${line#* }
r=${r%% *}
There are other
string manipulation techniques available too, it the above isn't satisfactory. Using
read, for example:
Code:
read _ r _ <<<"$line" #_ is a disposable variable for dumping the data we don't need.
But as I showed above, the whole of the above section can be condensed into a single
awk command anyway.