在Bash中拆分带有|字符的字符串,并从第一行导出环境变量

在Bash中拆分带有|字符的字符串,并从第一行导出环境变量,bash,sed,environment-variables,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或其他结构化响应格式,这是我必须使用的 我的目标是通过分

我从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

将它们作为系统环境变量(直到重新启动或下次执行my
.sh
脚本)或在shell脚本本身的上下文中使用。

这是您想要的:

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

awk-F'|''BEGIN{ORS=“”}{for(i=1;i如果标题是固定的,
读取就足够了:

IFS='|' read account uname upass mac ip tariff download upload < <(tail -n1 test.txt)
echo $account $ip
按要求取3:
awk

原件供参考

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"
输出:

11122 192.168.1.2
$: 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
中,源化输出也应该满足您的需要。

使用粘贴和GNU-sed:

. <(paste -d= <(sed -n '1s/|/\n/gp' test.txt) <(sed -n '2s/|/\n/gp' test.txt))
将输出:

11122 24:A4:3C:DA:22:B2 192.168.1.2

不。它不导出变量。请再次阅读我的问题。我已编辑了我的答案。为了将这些值设置为环境变量,您需要在某个位置定义它们。/etc/environment是一个很好的位置。要实现这一点,只需重定向输出。请记住,您需要具有sudo访问权限才能修改我提到的文件,而且,您还需要o注销并登录以查看反映的更改。这比公认的答案更合适。我建议避免使用
seq
,而只是在数组上迭代。类似于
I=0;对于“${headers[@]}”中的k;执行echo printf-v“$k”${data[$(++I))}”;完成
啊。好的,那么,我会看看我是否能生成一个功能替代方案。给我一点。很乐意帮忙。;)如果我们使用
awk
只使用
awk
将输出文件写入源代码,那么就更容易了,lolI只是持久性的。>;o]
paste
不可用。我在
sh
下运行此操作,而
bash
也不可用。我需要处理以下操作:
read
awk
sed
head
cat
grep
和其他基本程序。我正在busybox/mips GNU linux上运行此程序。
$: 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
. <(paste -d= <(sed -n '1s/|/\n/gp' test.txt) <(sed -n '2s/|/\n/gp' test.txt))
. <(datamash -t '|' --output-delimiter='=' transpose < test.txt)
echo $account $mac $ip
11122 24:A4:3C:DA:22:B2 192.168.1.2