For loop scripting

Hi there again,
I need some help in figuring out how to execute a for loop command to come up with my desired output. I have individual monthly files and a single file containing a list of location data for 1 year. I want to do a loop where for each monthly file say Jan.hdf, if will read the location values corresponding to month 1.

input files:
Monthly files: Jan.hdf ..Dec.hdf
location.dat containing the ff. information:
lon lat month
123.5 12.4 1
124.5 12.3 1
125.5 12.2 2
126.5 12.1 2
127.5 12.0 2... and so on 

thanks much. i hope u can help me out resolve this.

cheers, irene

What output do you want? You've shown the input? -- the structure of the files you want to read?
sort of pseudo-code is, it assumes the on hdf files in the current directory are jan .. dec.hdf----:

awk ' [awk script to give you your output] '  *.hdf > location.dat

There is no need for a loop based on what you've said so far.

If the input file structure matches the output file you can combine all files this way:

cat *.hdf > location.dat

hi, this the sample code i want to have in concept.

files ="$(ls *.hdf)"
for i in $files; do
    read lines of location.dat
    plot $i;    
    overlay location points corresponding to similar month
done

Sorry, i'm very poor in explaining. basically, i would like to have a visual output where only location points from january (column 3 of locations.dat=1) will be overlaid on my monthly plot for january (file 1) and so on. thanks much

Is this what you're looking for?

[root@hostname test]# ls -rt *.hdf
Jan.hdf  Feb.hdf
[root@hostname test]# cat location.dat
lon lat month
123.5 12.4 1
124.5 12.3 1
125.5 12.2 2
126.5 12.1 2
127.5 12.0 2

[highlight=bash]#! /bin/bash

mnths=( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec )

for files in `ls -rt *.hdf`
do
echo "lon lat for the month of $files"
mt=`basename $files .hdf`
i=0
for m in ${mnths[@]}
do
i=$(($i + 1))
if [ "$mt" == "$m" ]
then
mt=$i
break
fi
done
while read LINE
do
[[ `echo $LINE | cut -d" " -f1` == "lon" ]] && continue
[ `echo $LINE | cut -d" " -f3` -eq $mt ] && echo $LINE | cut -d" " -f1-2
done < location.dat
done[/highlight]

[root@hostname test]# ./test.sh
lon lat for the month of Jan.hdf
123.5 12.4
124.5 12.3
lon lat for the month of Feb.hdf
125.5 12.2
126.5 12.1
127.5 12.0

---------- Post updated at 10:34 ---------- Previous update was at 10:07 ----------

Slightly quicker in Perl.

[highlight=perl]#! /usr/bin/perl -w
use strict;
my ($file, $m);
my %months = ( "Jan" => 1, "Feb" => 2, "Mar" => 3, "Apr" => 4, "May" => 5, "Jun" => 6,
"Jul" => 7, "Aug" => 8, "Sep" => 9, "Oct" => 10, "Nov" => 11, "Dec" => 12);

for $file (glob "*.hdf") {
print "lon lat for $file\n";
$file =~ s/\.hdf//g;
for (keys %months) {
if ($file eq $) { $m = $months{$} }
}
open I, "< location.dat";
for (<I>) {
if (/^lon/) { next }
if (/$m$/) { print $_ }
}
close I;
}[/highlight]

hi thanks for the reply. If i want to save the output file to individual file name from your code, how will i do that? I think i can start from it. this is my messy code supposedly:

#!/bin/bash

files="$(ls *.hdf)"

for f in $files; do
   for line in location.dat; do
      grdimage $f $range -Csst.cpt -JM$scale -P -B10g5 -K -O >> "$f".ps (this will produce an image map for each month)
      psxy $line $range -JM$scale -B10g5 -Sc0.05 -Gblack -P -K -O "$f".ps (this will plot location points on the output image from earlier command-
this is where i need to tell the program that it will only plot location points from the list for the given month)
    done 
done

thanks much.

Changes from the previous bash script are highlighted in blue. This way, you can get separate files 'Jan.out', 'Feb.out'... each containing information about that particular month. Manipulate the code to suit your requirement.

#! /bin/bash

mnths=( Jan Feb Mar Apr Jun Jul Aug Sep Oct Nov Dec )

for files in `ls -rt *.hdf`
do
    mt=`basename $files .hdf`
    echo "lon lat for the month of $files" >> $mt.out
    i=0
    for m in ${mnths[@]}
    do
        i=$(($i + 1))
        if [ "$mt" == "$m" ]
        then
            mt_num=$i
            break
        fi
    done
    while read LINE
    do
        [[ `echo $LINE | cut -d" " -f1` == "lon" ]] && continue
        [ `echo $LINE | cut -d" " -f3` -eq $mt_num ] && echo $LINE | cut -d" " -f1-2 >> $mt.out
    done < location.dat
done
1 Like

thanks much,:slight_smile:

---------- Post updated at 03:30 PM ---------- Previous update was at 03:11 PM ----------

hi again, i'm thinking of just working on my location.dat file. if supposed i just want loop inside the lines of the .dat file and print lon, lat values using awk for specific month, is this possible and whats the appropriate code for this? thanks much. i think this would be much simple for me.

output file:

lon lat for jan > month1
lon lat for feb > month2

It is possible. Suppose you have a variable LINE containing LINE="123.5 121.2 1" and you want just the lon and lat values, this can be achieved by echo $LINE | awk '{print $1,$2}' . This is same as echo $LINE | cut -d" " -f1-2 .

cut -d" " -f1-2 --> cut out field (-f) 1 to 2 with delimiter (-d) as space.

Pretty much the same.

1 Like

bunch of thanks!:slight_smile: