Skip to content
Advertisement

Read lines from a file and tokenize each line to extract specific word in shell script

I wrote a shell script to read all lines from a file, tokenized each line to extract particular word. First line is read correct, but from the second line the expected word is not reading correctly. Looking forward for your suggestions.

while read -ra line; 
    do
        netmask="${line[5]}"
        echo "netmask is $netmask" // first line reading is correct, second line onwards its showing 
                                      wrong output
        IFS='.' tokens=($netmask) 
        prefix=0
        for i in 0 1 2 3
        do
            var="${tokens[$i]}"
            # i have a logic to calculate number of 1's in the number.
        done 
done < routes.sh

Contents of route.sh are

route add -net 10.212.220.0 netmask 255.255.255.0 gw 10.213.248.1
route add -net 10.212.220.0 netmask 255.255.128.0 gw 10.213.248.1

Actual output

netmask is 255.255.255.0
netmask is 128

Expected output

netmask is 255.255.255.0
netmask is 255.255.128.0

Extra Note:

My objective is to (network concept)

  1. Read all lines from a file (each line depicts a route)
  2. From each line extract the netmask (e.g.: 255.255.255.255)
  3. Tokenize “255.255.255.255” with ‘.’, so we get 4 numbers, calculate the number of 1s in each token, add them up. That would be prefix length for the network IP.

Advertisement

Answer

The problem is that you set IFS='.', so for the second read on the array line will be incorrectly set.

One way to fix it is by saving the original IFS and then resetting it when appropriate. For example,

OldIFS=$IFS
while read -ra line; do
    netmask="${line[5]}"
    echo "netmask is $netmask"
    IFS='.' tokens=($netmask)
    prefix=0
    for i in 0 1 2 3; do
        var="${tokens[$i]}"
    done
    IFS=$OldIFS
done < routes.sh

You must be careful when changing IFS, otherwise weird things will happen.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement