'Parsing list in bash

I have a text file which looks like this:

...
unique_trigger = item1
                 item2
                 item3
                 ...
                 itemN
unique_end_trigger
...

Is there a quick (maybe on-liner if possible) bash script I could use to parse the file and pipe item1 item2 item3... into another command? The number of items is not determined. I looked at other bash scripts to read variables out of a file but they either source it, parse each item manually (predetermined list length) or assign a environment variable to each item based on its name (which is not my case). I am looking for something like this:

parse_command file.txt | other_command


Solution 1:[1]

perl:

perl -0777 -pE 's/.*unique_trigger\s*=\s*(.*)unique_end_trigger.*/$1/s; s/^\s+//gm' file.txt
item1
item2
item3
...
itemN

Solution 2:[2]

One-liner

cat file.txt | tr -s "[:space:]" " " | \
sed -En "s/(.*)(unique_trigger = )(.*)(unique_end_trigger)/\3/p" | \
other_command

Solution 3:[3]

 awk '/unique_end_trigger/&&--f||f||/unique_trigger/&&f++ {printf $1 " "}' <(sed 's/unique_trigger =/ & \n /' input_file)

item1 item2 item3 ... itemN

Solution 4:[4]

Not quite a one-liner, but it should do the trick as long as your triggers don't contain spaces.

flag=0
while read tr eq it ; do
        if [ "$tr" = "unique_trigger" ] ; then
                echo "$it"
                flag=1
        elif [ $flag = 1 ] ; then
                if [ "$tr" = "unique_end_trigger" ] ; then
                        flag=0
                else
                        echo "$tr"
                fi
        fi
done

Solution 5:[5]

Two solutions, using the same concept. When the start trigger is found, add the item (3rd item in the line) to a string. Until the end trigger is found, the item is the only work in the line, so add it to the string. Output the string at the end.

Bash parsing

#!/bin/bash

file="file.txt"
start_trigger="unique_trigger"
end_trigger="unique_end_trigger"
items=''
between_trigger="no"

while IFS= read -r line; do
    #echo "-----$line-----"
    # Start trigger lines
    if [[ "$line" =~ "$start_trigger =" ]]
    then
        items="$items $(echo "$line" | awk '{print $3}')"
        between_trigger="yes"
        continue
    fi
    # End trigger lines
    if [[ "$line" =~ "$end_trigger" ]]
    then
        between_trigger="no"
        continue
    fi
    # Lines between start and end trigger
    if [[ "$between_trigger" == "yes" ]]
    then
        items="$items $line"
        continue
    fi
done < "$file"

echo ">>$items<<"

Using it: script.bash | xargs echo

Replace echo by any command.


Awk version

BEGIN {
    output = ""
    between = "no"
}
/unique_end_trigger/ {
    between = "no";
}
/.*/ {
    if (between == "yes") output = output " " $1
}
/unique_trigger/ {
    between = "yes";
    output = output " " $3;
}
END { print output }

Using it: awk -f script.awk file.txt | xargs echo

Replace echo with whatever command you want.

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 glenn jackman
Solution 2 seeker
Solution 3 ufopilot
Solution 4 Ljm Dullaart
Solution 5 Nic3500