简体   繁体   中英

Bash: How to read previous line while reading a file

I'm writing a bash script that should read through a file having certain lines of device configs. The idea is to read and print a line from file. If 'bel' is found in the current line, then check the next line if it has keyword X that is "awk '{print $3}'" of the current line. If keywordA is NOT found in the current line, go to next line and continue the search for 'bel'.

If the 2nd line has keyword X, then print success, if not, print fail. No need to print the 2nd line itself. However, and this is the part I can't figure out, if the 2nd line does NOT have keywordB and it prints fail, then re-search this line for keywordA and basically use the logic again.

Below is what I have come up with:

#! /bin/bash
Input="/tmp/temp2"
while read LINE
do
    if $(echo "$LINE" | grep -q bel)
    then
        echo "$LINE"
        intf=`echo $LINE | awk  '{print $1" "$2" "$3}'`
        echo $intf
        read LINE
        if $(echo "$LINE" | grep -q "$intf " )
        then
            echo "Success"
        else
            echo "Fail"
        fi
    fi
done < "$Input" > /tmp/temp3

Essentially, I just want it to re-read the 2nd line and search for keywordA. But as the code is doing a read LINE inside the loop as well, it moves to the 3rd line when it iterates.

Sample Input file:

idk:idk1-baf1:set interfaces ae0 description "baf -> bel"

idk:idk1-baf1:set interfaces ae6 description "baf -> bel"

idk:idk1-baf1:set interfaces ae6 aggregated-ether-options minimum-links 4

idk:idk1-baf1:set interfaces ae12 description "baf -> bel"

idk:idk1-baf4:set interfaces ae12 aggregated-ether-options minimum-links 4

idk:idk1-baf4:set interfaces ae131 aggregated-ether-options minimum-links 4

idk:idk1-baf4:set interfaces ae133 aggregated-ether-options minimum-links 4

Current Output:

idk:idk1-baf1:set interfaces ae0 description "baf -> bel"

Fail

idk:idk1-baf1:set interfaces ae12 description "baf -> bel"

Fail

So the current output is basically skipping the line:

idk:idk1-baf1:set interfaces ae6 description "baf -> bel"

Expected Output:

idk:idk1-baf1:set interfaces ae0 description "baf -> bel"

Fail

idk:idk1-baf1:set interfaces ae6 description "baf -> bel"

Success

idk:idk1-baf1:set interfaces ae12 description "baf -> bel"

Fail

I don't mind if anyone can tweak the code, or suggest a completely different solution :)

You can do with awk

awk '{if(j==1){if(i==$1$2$3){print "success"}else{print "fail"}j=0} if($0 ~ /bel/){i=$1$2$3;j=1;print} }' file

It will print:

idk:idk1-baf1:set interfaces ae0 description "baf -> bel"
fail
idk:idk1-baf1:set interfaces ae6 description "baf -> bel"
success
idk:idk1-baf1:set interfaces ae12 description "baf -> bel"
fail

Explanation

  • By default awk will take white-space as input field separator.

  • $0 : represents current row/line.

  • $1 : represents 1st column of current row/line.

  • $2 : represents 2nd column of current row/line.

    .... and so on.

  • $0 ~ /bel/: will search "bel" string in current row/line.

  • i=$1$2$3 : If "bel" is present in row/line then it will store value of first 3 column of current line in a variable i.

  • j=1 : consider this as a flag. if "bel" is present in line. it will be equal to 1.

  • print : If "bel" is present then it will print current row/line.


Now coming to the another if statement.


  • if(j==1) :Checking if j(ie flag here) is equal to 1.if it's equal to 1 means previous line has "bel" as string.

  • if(i==$1$2$3){print "success"}else{print "fail"}j=0 : Here it is comparing i(stored 1st 3 column of previous line) to 1st 3 column of current line. If it matches then it will print "success" else will print fail and it will set j=0.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM