ksh - Read input from file and output CSV i same row

Hello

I have the following output and want the output to look:

FROM:

GigabitEthernet0/0 is up, line protocol is up
     1 input errors, 0 CRC, 0 frame, 1 overrun, 0 ignored
     275 output errors, 0 collisions, 3 interface resets
GigabitEthernet0/1 is up, line protocol is up
     0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored
     42 output errors, 0 collisions, 3 interface resets

TO: (in CSV format)

Interface, Input Errors, Output Errors
GigabitEthernet0/0, 1, 275
GigabitEthernet0/1, 0, 42

When I put the above in a for loop I get staggered outputs as I'm greping on the turn of every loop

Here's my script

for line in $(cat $DATAFILE/$rname.intfs)
do
     intf=$(echo $line | grep "line protocol is " | awk '{print $1}')
     inerrs=$(echo $line | grep "input error" | sed 's/^[ \t]*//;s/[ \t]*$//' | awk '{print $1}')
     outerrs=$(echo $line | grep "output error" | sed 's/^[ \t]*//;s/[ \t]*$//' | awk '{print $1}')
     echo "$intf,$inerrs,$outerrs" >intf.csv
done

Any help is appreciated

thanks

Jay

With sed :

sed 's/ .*$/,/;N;s/ input.*$/,/;N;s/ output.*$//;s/\n//g' < $DATAFILE/$rname.intfs

Output:

GigabitEthernet0/0,     1,     275
GigabitEthernet0/1,     0,     42

Works for me on Ubuntu 16.04.03, GNU sed 4.2.2 but it should work for any sed.

Andrew

Welcome JayJay2018,

Please wrap all code, files, input & output/errors in CODE tags (highlight and press the CODE toolbar button)
It is easier to read as code because it is mono-spaced and preserves multiple spaces for indenting and fixed-width data. I have adjusted your initial post for you. If you click on the edit button, you can see how.

My first suggestion is to lose the $(cat $DATAFILE..... bit. It is far more efficient to have your loop like this:-

while read line
do
   whatever
   echo "Here is my output"
done < $DATAFILE/$Rname.intfs > intf.csv

The output is written as one operation to the file rather than lots of separate statements, which (by the way) overwrite the file, so you will only actually see the last record being output. You also write the output line for every input line, so you will get a variety of output being built up as records are read. As the values are not reset, after the first complete 'chunk' of the output, the next will start with the old values filled in which is probably confusing.

If you are certain of your input format, you can probably do this:-

while read firstline
do
   read secondline
   read thirdline
   # Some processing here
   echo                                       # Whatever you have built
done < $DATAFILE.......  > intf.csv

When it comes to processing your lines to get the values you want, you are also calling far more steps than you need. With ksh or bash, you can split up the line as you read it. You need just the first item of each line, so this brings my first suggested code to this:-

while read intf junk
do
   read inerrs  junk
   read outerrs junk

   echo "$intf, $inerrs, $outerrs"
done < $DATAFILE/$rname.intfs > intf.csv

Does that help?

If I've confused you, I apologise. If the script produces errors, please paste them in to the thread, wrapped in CODE tags of course, and I will have another think.

Kind regards,
Robin

Robin, Andrew, thanks for your reply

The sed solution works perfectly! Genius! :b:

thanks again

Jay

Try also

awk 'BEGIN {print "Interface, Input Errors, Output Errors"} {printf "%s%s", $1, !(NR%3)?RS:", "}' file
Interface, Input Errors, Output Errors
GigabitEthernet0/0, 1, 275
GigabitEthernet0/1, 0, 42
1 Like