如何从 bash 中的文本文件格式化变量?

how to format a variable from text file in bash?

我一直卡在这个问题上,试了很多方法都不行。

假设我有一个文本文件,内容如下

mark_line
variable1
value1
value2
mark_line
variable2
value3
mark_line
variable3
value4
value5
value6
value7
mark_line
...
...
mark_line

等等,基本上在每个mark_line之间,第一行是变量名,其余是该变量的值,可以是一行或多行行

期待输出变得像

变量1="value1 value2"

变量2="value3"

varaible3="value4 value5 value6 value7"

等等...

我认为这需要一个 whilefor 循环,但我想不出合适的方法。

任何提示或想法将不胜感激。

仅根据生成一堆赋值语句的要求(但不一定执行所述语句),我们将从示例数据文件开始:

$ cat mark_line.dat
mark_line
variable1
value1
value2
mark_line
variable2
value3
mark_line
variable3
value4
value5
value6
value7
mark_line
variable4
value8
mark_line
mark_line
mark_line

接下来是一些 awk 代码,它将 variable/value 个条目打印到一行,仅当我们看到 [=15= 时才生成换行符 (\n) ]条目:

$ awk '
/mark_line/ { printf "\n" ; next }
            { printf [=11=]" "}
' mark_line.dat

<blank_line>
variable1 value1 value2
variable2 value3
variable3 value4 value5 value6 value7
variable4 value8
<blank_line>
<blank_line>

然后我们将解析出空白行并让 while 循环将等号和双引号添加到我们的输出:

$ awk '/mark_line/ { printf "\n" ; next } { printf [=12=]" "}' mark_line.dat | \
egrep -v '^$' | \
while read -r myvar myvals
do
    echo "${myvar}=\"${myvals}\""
done

variable1="value1 value2"
variable2="value3"
variable3="value4 value5 value6 value7"
variable4="value8"

注意:此解决方案假设每个 variable? 至少有一个 value? 与之关联,否则 variable? 至少没有一个value? 将生成输出:variable5=""

从这里我假设 OP 已经有了关于如何使用此输出的计划(例如,也许根据@kaylum 的评论使用 eval 命令?)。

你会尝试以下方法吗:

awk -v RS="mark_line\n" -v FS="\n"  '
        /[^[:blank:]]/ {                # skip blank lines
                sub("\n$", "", [=10=])      # remove trailing newline
                printf("%s=", )       # print "variablen=" portion
                str = 
                for (i=3; i<=NF; i++) str = str " " $i
                print "\"" str "\""     # print "value1 value2 .." portion
        }
' file

Printf 可以写入 var,让我们使用它

$ printf --help
printf: printf [-v var] format [arguments]
    Formats and prints ARGUMENTS under control of the FORMAT.

    Options:
      -v var    assign the output to shell variable VAR rather than
            display it on the standard output
...

已创建测试文件

$ cat test
mark_line
variable1
value1
value2
mark_line
variable2
value3
mark_line
variable3
value4
value5
value6
value7

以及处理它的脚本

#!/bin/bash

data=$(cat test)      # load test file to this var
delimiter='mark_line' # set  delimiter to 'mark_line'

# we'll loop through data with this function
var_creator () {
    while [[ $@ ]]; do
          # if 1st_arg='mark_line', remember 2nd_arg as new_var, add to vars array, remove 2 args
          [[  == "$delimiter" ]] && { new_var=; vars+=(); shift 2; }
          printf -v $new_var "${!new_var} " # the 1st_arg is our value coz we shift args, add it to new_var
          shift # remove 1st arg
    done
    # and this one need to remove spaces in front of vars and to print them
    for var in ${vars[@]}; { printf -v $var "${!var# }"; printf "$var=\"${!var# }\"\n"; }
}

var_creator $data # run process

输出

variable1="value1 value2"
variable2="value3"
variable3="value4 value5 value6 value7"