我希望你能帮助我。 我尝试分离一个字符串:
#!/bin/bash
file=$(<sample.txt)
echo "$file"
文件本身包含如下值:
(;FF[4]GM[1]SZ[19]CA[UTF-8]SO[sometext]BC[cn]WC[ja]
我需要的是一种在[]之间提取值并将它们设置为变量的方法,例如:
$FF=4
$GM=1
$SZ=19
and so on
但是,某些文件不包含所有值,因此在某些情况下没有FF [*]。在这种情况下,程序应使用值“99”
我该怎么做?
非常感谢你的帮助。 问候 克里斯
答案 0 :(得分:1)
这可能有点过于复杂,但这是另一种方式:
grep -Po '[-a-zA-Z0-9]*' file | awk '!(NR%2) {printf "declare %s=\"%s\";\n", a,$0; next} {a=$0} | bash
通过仅打印所需的块来过滤文件:
$ grep -Po '[-a-zA-Z0-9]*' a
FF
4
GM
1
SZ
19
CA
UTF-8
SO
sometext
BC
cn
WC
ja
重新格式化,以便指定声明:
$ grep -Po '[-a-zA-Z0-9]*' a | awk '!(NR%2) {printf "declare %s=\"%s\";\n", a,$0; next} {a=$0}'
declare FF="4";
declare GM="1";
declare SZ="19";
declare CA="UTF-8";
declare SO="sometext";
declare BC="cn";
declare WC="ja";
最后管道进行bash以便它被执行。
注意第二步也可以改写为
xargs -n2 | awk '{print "declare"$1"=\""$2"\";"}'
答案 1 :(得分:1)
我使用;
或[
或]
作为awk的字段分隔符来写这个
$ line='(;FF[4]GM[1]SZ[19]CA[UTF-8]SO[sometext]BC[cn]WC[ja]'
$ awk -F '[][;]' '{for (i=2; i<NF; i+=2) {printf "%s=\"%s\" ", $i, $(i+1)}; print ""}' <<<"$line"
FF="4" GM="1" SZ="19" CA="UTF-8" SO="sometext" BC="cn" WC="ja"
然后,评估当前shell中的输出:
$ source <(!!)
source <(awk -F '[][;]' '{for (i=2; i<NF; i+=2) {printf "%s=\"%s\" ", $i, $(i+1)}; print ""}' <<<"$line")
$ echo $SO
sometext
要处理默认的FF值:
$ source <(awk -F '[][;]' '{
print "FF=99"
for (i=2; i<NF; i+=2) printf "%s=\"%s\" ", $i, $(i+1)
print ""
}' <<< "(;A[1]B[2]")
$ echo $FF
99
$ source <(awk -F '[][;]' '{
print "FF=99"
for (i=2; i<NF; i+=2) printf "%s=\"%s\" ", $i, $(i+1)
print ""
}' <<< "(;A[1]B[2]FF[3]")
$ echo $FF
3
答案 2 :(得分:0)
根据您的要求:
while IFS=\[ read -r A B; do
[[ -z $B ]] && B=99
eval "$A=\$B"
done < <(exec grep -oE '[[:alpha:]]+\[[^]]*' sample.txt)
尽管使用关联数组会更好:
declare -A VALUES
while IFS=\[ read -r A B; do
[[ -z $B ]] && B=99
VALUES[$A]=$B
done < <(exec grep -oE '[[:alpha:]]+\[[^]]*' sample.txt)
您可以同时访问密钥("${!VALUES[@]}"
)和值"${VALUES['FF']}"
。
答案 3 :(得分:0)
我可能会这样做:
set $(sed -e 's/^(;//' sample.txt | tr '[][]' ' ')
while (( $# > 2 ))
do
varname=${1}
varvalue=${2}
# do something to test varname and varvalue to make sure they're sane/safe
declare "${varname}=${varvalue}"
shift 2
done