Home > Mobile >  read text file two words at a time in a loop in bash
read text file two words at a time in a loop in bash

Time:07-27

I have a text file with a space separated list of numbers (lat/lon) that looks like this :

-8.000 43.860 -9.000 43.420 -9.350 43.220 -9.388 42.893 -9.000 42.067 -8.935 41.308 -9.000 40.692 -9.278 40.000 -9.324 39.550 -9.518 39.387 -9.777 38.883 -9.285 38.378 -8.909 38.293 -8.951 38.000 -8.965 37.953 -8.917 37.833 -8.913 37.667 -8.915 37.500 -8.975 37.333 -9.017 37.167 -9.045 37.000

I know how to loop through the numbers one by one in bash like this

awk '{ for ( i = 1; i < NF;   i ) print $(i); }' example.txt |
while IFS= read -r lon lat
do 
    echo processing: "$lon $lat" 
done

giving:

processing: -8.000 
processing: 43.860 
processing: -9.000 
processing: 43.420 
processing: -9.350 
processing: 43.220 

etc, but how can I loop through the file pair-wise?

i.e. something like (but this obviously doesn't work):

while IFS= read -r lon lat
do 
    echo processing: "$lon $lat " 
done

to give me lon=-8, lat=43.86 on the first loop etc...?

CodePudding user response:

You can read all the fields in a line into an array (with read -a), and then loop over that:

while read -r -a fields; do
    for ((i=0; i < ${#fields[@]}; i  = 2)); do
        echo "${fields[i]}" "${fields[i 1]}"
    done
done < example.txt
-8.000 43.860
-9.000 43.420
-9.350 43.220
...

CodePudding user response:

$ awk '{ 
    for ( i = 1; i < NF; i =2 ) 
        print $i, $(i 1) 
}' file | 
while read -r lon lat
do
    echo processing: "$lon $lat"
done

Output:

processing: -8.000 43.860 
processing: -9.000 43.420 
processing: -9.350 43.220 
...

CodePudding user response:

Using sed

$ sed -E  '/([0-9.-]  [0-9.-] ) ?/s//processing: \1\n/g' example.txt
processing: -8.000 43.860
processing: -9.000 43.420
processing: -9.350 43.220
processing: -9.388 42.893
processing: -9.000 42.067
...

CodePudding user response:

Using xargs

$ echo "key1 value1 key2 value2" | xargs -n2 
key1 value1
key2 value2

$ echo "a b c e f g" | xargs -n3 
a b c
e f g

while IFS= read -r lon lat; do 
    echo processing: "$lon $lat" ; 
done < <(xargs -n2 <example.txt)

processing: -8.000 43.860 
processing: -9.000 43.420 
processing: -9.350 43.220 
processing: -9.388 42.893 
...

Without while loop

$ xargs -n 2 sh -c 'echo processing: lon $1 lat $2' argv0 <example.txt
processing: lon -8.000 lat 43.860
processing: lon -9.000 lat 43.420
processing: lon -9.350 lat 43.220
processing: lon -9.388 lat 42.893
processing: lon -9.000 lat 42.067
...

CodePudding user response:

Using xargs:

xargs -n 2 env LC_NUMERIC=C printf 'Processing: %.3f %.3f\n' < example.txt 

Using only awk, awkscript:

#!/usr/bin/env -S awk -f
{
  i = 1;
  while(i < NF) {
    lon = $i;
    i  ;
    lat = $i;
    i  ;
    printf("Processing: %.3f %.3f\n", lon, lat);
  }
}
chmod  x awkscript
./awkscript example.txt

Or one-line: awk '{i=1;while(i<NF){lon=$i;i ;lat=$i;i ;printf("Processing: %.3f %.3f\n",lon,lat);}}' < example.txt

  •  Tags:  
  • bash
  • Related