-1

I have a file which would contain something like:

CUSTOMER_MSISDNS
447999999999

The list of MSISDNs can carry on and be unlimited, and there is no set position where this section may be in the file due to expanding top elements, so to find the line number I use:

MSISDN_LINE=$(cat -n ${FILE} | grep 'CUSTOMER_MSISDNS' | awk '{print $1}')

This will return say 29 the line of CUSTOMER_MSISDNS in my ${FILE} element. I then use a while loop to read all lines after that number by:

LINE=1
while read line
do
    if [ $LINE -le $MSISDN_LINE ]
    then
        LINE=$(($LINE+1))
        continue
    fi
done

However I keep finding that it will always leave the last line off the file out. Ending the line in this example on line 29 excluding line 30 with the actual MSISDN on.

To solve this I added a character return into the file which then allowed the MSISDN on line 30 to be selected, however I cannot guarantee that there will be a character return when I am not testing. Any Ideas on how I can solve this.

cat ${FILE} | wc -l would also not show the last line of the file
whoan
  • 8,143
  • 4
  • 39
  • 48
Charabon
  • 737
  • 2
  • 11
  • 23
  • I have re-read your question and I do not understand what is the problem – Jdamian Dec 09 '14 at 11:08
  • Basically, If I have my last line not as a new line it will not pick up the line I actually want to read into the while loop i.e. for it to pick up this middle line I need the format to be: 1: CUSTOMER_MSISDNS 2: 447999999999 3: . Line numbers are shown for example (123) – Charabon Dec 09 '14 at 11:33

3 Answers3

1

If the last line is missing a new line, read still gets the content of the line, but exits with status 1 to indicate that it reached the end of the file before reading a complete line. You can modify your while loop to handle this with

while read line || [[ -n $line ]]; do
    ...
done

For all but the last line, read's exit status will be 0. For the last line, it may be 1, but continue the loop if read still managed to read some data. Only when read exits with a non-zero value and it reads no data do you want to exit the loop.

chepner
  • 497,756
  • 71
  • 530
  • 681
1

Instead of using a while loop to read line by line, I used tail.

tail -n +$(($MSISDN_LINE+1)) ${FILE}

This is finding the MSISDN_LINE adding 1 to it to ensure it goes to the next line where the numbers are and then reading all lines below. No extra line is needed to ensure the file is read properly.

-n = Read from line with ability to use + or - depending on the direction in which you need to go.

Charabon
  • 737
  • 2
  • 11
  • 23
0

You might be getting multiple lines from your code

MSISDN_LINE=$(cat -n ${FILE} | grep 'CUSTOMER_MSISDNS' | awk '{print $1}')

Instead you need max line number, so you should do it as:

MSISDN_LINE=$(grep -n 'CUSTOMER_MSISDNS' $FILE | tail -1 | awk -F: '{print $1}')
SMA
  • 36,381
  • 8
  • 49
  • 73
  • 1
    thank you for your answer @almas, while that is true, It does not solve the issue I was having, even with the change in code I am still not able to return the last line of the file – Charabon Dec 09 '14 at 11:10
  • Did you tried running this command on command line `grep -n 'CUSTOMER_MSISDNS' $FILE | tail -1` with file that you are going to get in your script? It should work. – SMA Dec 09 '14 at 12:04