'How to properly store variable in a Loop in Bash?

May I ask how to loop in a while? he's my attempt on creating a file that will generate the data in a specific way. My aim is to append the rule into one single line, regardless of application number.

My Code is:

#!/bin/bash
file="temp3"
while IFS= read -r line
do
        # display $line or do somthing with $line
                #printf '%s\n' "$line"
                echo
                printf '%s\n' "$line" | grep "MySource" | awk '{printf " " $5}'
                printf '%s\n' "$line" | grep "MySource-" | awk '{printf " " $7 " " $8}'
                printf '%s\n' "$line" | grep "MyDestination" | awk '{printf " " $7 " " $8}'
                printf '%s\n' "$line" | grep "MyAppName" | awk '{printf " " $8}' #| awk '{printf " " $7 " " $8}'

                VARIABLE=$(printf '%s\n' "$line" | grep "source" | awk '{printf " " $5}')
                VARIABLE=$(printf '%s\n' "$line" | grep "source-" | awk '{printf " " $7 " " $8}')
                VARIABLE=$(printf '%s\n' "$line" | grep "destination" | awk '{printf " " $7 " " $8}')
                VARIABLE=$(printf '%s\n' "$line" | grep "application" | awk '{printf " " $8}')

                done <"$file"

echo $VARIABLE
printf $VARIABLE

here's the contents of my file

zone lab zone trust  new-rule-162 match source-address MySourceName1
zone lab zone trust  new-rule-162 match source-address MySourceName2
zone lab zone trust  new-rule-162 match destination-address MyDestinationName1
zone lab zone trust  new-rule-162 match destination-address MyDestinationName2
zone lab zone trust  new-rule-162 match application MyApplicationName1
zone lab zone trust  new-rule-162 match application MyApplicationName2
zone lab zone trust  new-rule-162 match application MyApplicationName3
zone lab zone trust  new-rule-162 then permit

Hopefully, ill be able to expand this in a way that I will be able to sort them out in the following manner.

new-rule-162 source-address MySourceName1 destination-address MyDestinationName1 application MyAppName1 MyAppName2 MyAppName3

The ultimate goal. In this case since, there are 2 sources and 2 destinations, the equivalent output should be 4 rows with all rows indicating the total X number of apps (4) and the permission "permit"

new-rule-162 source-address MySourceName1 destination-address MyDestinationName1 permit application MyAppName1 MyAppName2 MyAppName3 
new-rule-162 source-address MySourceName1 destination-address MyDestinationName2 permit application MyAppName1 MyAppName2 MyAppName3  
new-rule-162 source-address MySourceName2 destination-address MyDestinationName1 permit application MyAppName1 MyAppName2 MyAppName3 
new-rule-162 source-address MySourceName2 destination-address MyDestinationName2 permit application MyAppName1 MyAppName2 MyAppName3  


Solution 1:[1]

This code can help you to do it better

#!/bin/bash
while IFS=" " read -ra line; do
    # Set last Element equal to last element in array line avoid use awk
    lastElement=${line[-1]:-"Default value here"}

    echo "${line[4]} $lastElement ${line[-2]} where is the rest of the data ???"
# # For use a var here
# done <<<"$myVar"
done <log.txt

The output is.

new-rule-162 MySourceName source-address where is the rest of the data ???
new-rule-162 MyDestinationName destination-address where is the rest of the data ???
new-rule-162 MyApplicationName application where is the rest of the data ???

Note: You don't need to print in order to grep, just do: grep -q "Some string" <<<"$line"

if (grep -q "Some string" <<<"$line"); then
   Do some stuff     
fi

Or

(grep -q "Some text" <<<"$lone") && echo "Found" || echo "Not found"

Solution 2:[2]

I am assuming that the tags like new-rule-162 are unique.

$ cat input-file

zone lab zone trust  new-rule-162 match source-address MySourceName
zone lab zone trust  new-rule-162 match destination-address MyDestinationName
zone lab zone trust  new-rule-162 match application MyApplicationName
zone lab zone trust  new-rule-162 then permit


$ awk '
    $(NF-1)=="source-address"{src[$5]=$NF}      # Record src; index by 5th field (new-rule-162)
    $(NF-1)=="destination-address"{dst[$5]=$NF} # and dest
    $(NF-1)=="application"{app[$5]=$NF}         # and app name
    END {
        for (i in src)                          # For all entries
            printf "%s source-address %s destination-address %s application %s\n", i, src[i], dst[i], app[i]; # print the required parameters
        }' input-file

new-rule-162 source-address MySourceName destination-address MyDestinationName application MyApplicationName

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 anishsane