我有以下从Web服务获得的字符串:
user@server:~# cat test.txt
account|uname|upass|mac|ip|tariff|download|upload
11122|24a43cda22b2|O3v2L2oPE9|24:A4:3C:DA:22:B2|192.168.1.2|7|12582500|2097000
第一行是列名,第二行是它们各自的值。请注意,响应始终返回这两行,而不是更多。我不能使用JSON或其他结构化的响应格式,这是我必须使用的。
我的目标是用分隔符|
分割所有这些值,并使用列名作为变量名来设置环境变量(或在.sh
脚本中的变量)。
到目前为止,我可以使用以下命令用|
分别拆分两行:
user@server:~# head -n1 test.txt | sed 's/|/\n/g'
account
uname
upass
mac
ip
tariff
download
upload
user@server:~# head -n2 test.txt | sed 's/|/\n/g'
11122
24a43cda22b2
O3v2L2oPE9
24:A4:3C:DA:22:B2
192.168.1.2
7
12582500
2097000
在这里,我想定义变量,即。 $account, $uname
等具有以下值:
$account = 11122
$uname = 24a43cda22b2
将它们作为系统环境变量(直到重新启动或.sh
脚本的下一次执行)或在shell脚本本身的上下文中。
答案 0 :(得分:3)
按照要求3:
awk
$: awk -F'|' 'BEGIN{ ORS="" }
NR == 1 { for ( i=0; i <= NF; i++ ) { arr[i] = $i; }; }
NR == 2 { for ( i=1; i <= NF; i++ ) { printf "%s=%s\n", arr[i], $i; }; }
' test.txt > /tmp/vars
$: . /tmp/vars
第2点:为
sh
重写
希望这会有所帮助。 :)
$: cat parse
#! /bin/env sh
sed -n '
s/[|]/\n/g
1 w /tmp/names
2 w /tmp/vals
' $1
paste /tmp/names /tmp/vals | sed 's/\t/=/' >/tmp/vars
$: cat /tmp/vars
account=11122
uname=24a43cda22b2
upass=O3v2L2oPE9
mac=24:A4:3C:DA:22:B2
ip=192.168.1.2
tariff=7
download=12582500
upload=2097000
$: . /tmp/vars
$: echo $account
11122
供参考
printf -v
将为您写入指定的变量名称。
$: cat parse
#! /bin/env bash
{ IFS='|' read -a headers
IFS='|' read -a data
} < $1
declare -i ndx=0
for h in "${headers[@]}"
do printf -v "$h" "%s" "${data[ndx++]}"
done
echo "account=$account uname=$uname upass=$upass mac=$mac ip=$ip tariff=$tariff download=$download upload=$upload"
执行为:
$: parse test.txt >vars
输出:
$: cat vars
account=11122 uname=24a43cda22b2 upass=O3v2L2oPE9 mac=24:A4:3C:DA:22:B2 ip=192.168.1.2 tariff=7 download=12582500 upload=2097000
将这些值加载到范围中
$: parse test.txt >vars
$: . vars
即使在sh
中,采购输出也可以满足您的需求。
答案 1 :(得分:1)
这就是您想要的:
awk -F'|' 'BEGIN{ ORS="" } { for ( i=1; i<= NF && NR == 1; i++){ arr[i]=$i } ; if (NR == 1) next ; for ( i=1; i<= NF ; i++ ) { print arr[i]"="'\''$i'\''"\n" } } ' input.txt
account=11122
uname=24a43cda22b2
upass=O3v2L2oPE9
mac=24:A4:3C:DA:22:B2
ip=192.168.1.2
tariff=7
download=12582500
upload=2097000
EDIT:声明时不需要美元符号。 编辑:为了实际将其设置为环境变量,您可以将其输出重定向到文件 / etc / environment ,如下所示:
awk -F'|' 'BEGIN{ ORS="" } { for ( i=1; i<= NF && NR == 1; i++){ arr[i]=$i } ; if (NR == 1) next ; for ( i=1; i<= NF ; i++ ) { print arr[i]"="'\''$i'\''"\n" } } ' input.txt >> /etc/environment
您当然需要sudo
希望有帮助!
答案 2 :(得分:1)
如果标头是固定的,那么read
就足够了:
IFS='|' read account uname upass mac ip tariff download upload < <(tail -n1 test.txt)
echo $account $ip
输出:
11122 192.168.1.2
答案 3 :(得分:1)
使用粘贴和GNU sed:
. <(paste -d= <(sed -n '1s/|/\n/gp' test.txt) <(sed -n '2s/|/\n/gp' test.txt))
或者GNU datamash是否可用:
. <(datamash -t '|' --output-delimiter='=' transpose < test.txt)
然后:
echo $account $mac $ip
将输出:
11122 24:A4:3C:DA:22:B2 192.168.1.2