如何从 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"
等等...
我认为这需要一个 while 或 for 循环,但我想不出合适的方法。
任何提示或想法将不胜感激。
仅根据生成一堆赋值语句的要求(但不一定执行所述语句),我们将从示例数据文件开始:
$ 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"
我一直卡在这个问题上,试了很多方法都不行。
假设我有一个文本文件,内容如下
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"
等等...
我认为这需要一个 while 或 for 循环,但我想不出合适的方法。
任何提示或想法将不胜感激。
仅根据生成一堆赋值语句的要求(但不一定执行所述语句),我们将从示例数据文件开始:
$ 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"