bash 中的解析列表

Parsing list in bash

我有一个如下所示的文本文件:

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

是否有一个快速的(如果可能的话可能是在线的)bash 脚本我可以用来解析文件并通过管道 item1 item2 item3... 进入另一个命令?项目数量未确定。我查看了其他 bash 脚本以从文件中读取变量,但它们要么获取它,手动解析每个项目(预定列表长度),要么根据每个项目的名称为每个项目分配一个环境变量(这不是我的情况).我正在寻找这样的东西:

parse_command file.txt | other_command

不完全是 one-liner,但只要您的触发器不包含空格,它就可以解决问题。

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

One-liner

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

两种解决方案,使用相同的概念。找到启动触发器后,将项目(行中的第 3 个项目)添加到字符串中。在找到结束触发器之前,该项目是该行中的唯一作品,因此将其添加到字符串中。输出最后的字符串。

Bash解析

#!/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 }')"
        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<<"

使用它:script.bash | xargs echo

用任意命令替换echo


awk 版本

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

使用它:awk -f script.awk file.txt | xargs echo

用你想要的任何命令替换echo

perl:

perl -0777 -pE 's/.*unique_trigger\s*=\s*(.*)unique_end_trigger.*//s; s/^\s+//gm' file.txt
item1
item2
item3
...
itemN
 awk '/unique_end_trigger/&&--f||f||/unique_trigger/&&f++ {printf  " "}' <(sed 's/unique_trigger =/ & \n /' input_file)

item1 item2 item3 ... itemN