用|分割字符串Bash中的字符并从第一行导出环境变量

时间:2018-12-10 13:54:45

标签: bash sed environment-variables

我有以下从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脚本本身的上下文中。

4 个答案:

答案 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