将命令输出拆分为单独的变量



我正试图在macos时间机器上使用bash脚本。

我正在尝试读取时间机器备份目标的属性,然后如果有多个目标,则将目标拆分为变量。

从那里我可以使用ID进行备份。

我很难将输出分解为它们自己的变量。


rawdstinfo=$(tmutil destinationinfo)
echo "$rawdstinfo"
> ==================================================
Name          : USB HDD
Kind          : Local
Mount Point   : /Volumes/USB HDD
ID            : 317BD93D-7D90-494C-9D5F-9013B25D1345
====================================================
Name          : TM TEST
Kind          : Local
Mount Point   : /Volumes/TM TEST
ID            : 4648083B-2A11-42BC-A8E0-D95917053D27

我想计算==================================================,然后根据它们来划分变量,但我运气不好。

任何帮助都将不胜感激。

感谢

PS:为了明确我想要实现的目标,我想将每个目标驱动器发送到一个对象。从那里我可以比较装载点名称(在脚本的前面已经选择(;目的地ID";在该对象中,这样我就可以将它与其他tmutil命令(如(一起使用

#start a TM backup
sudo tmutil startbackup --destination $DESTINATIONID
#remove Migration HDD as a destination
sudo tmutil removedestination $DESTINATIONID

我喜欢使用awk来解析分隔的平面文件。我从你的问题中复制了tmutil输出,并将其粘贴到一个名为testdata.txt的文件中,因为我不是在Mac上这样做的。确保记录分隔符中的等号数与tmutil产生的值实际匹配。

这是解决方案的awk部分,它进入了我命名为timemachine_variables.awk:的文件

function ltrim(s) { sub(/^[ trn]+/, "", s); return s }
function rtrim(s) { sub(/[ trn]+$/, "", s); return s }
function trim(s)  { return rtrim(ltrim(s)); }
BEGIN {
RS="====================================================n";
FS=":|n"
}
{
i=FNR-1 
}
(FNR>1 && $1 ~ /Name/) {print "Name["i"]="trim($2)}
(FNR>1 && $3 ~ /Kind/) {print "Kind["i"]="trim($4)}
(FNR>1 && $5 ~ /Mount Point/) {print "Mount_Point["i"]="trim($6)}
(FNR>1 && $7 ~ /ID/) {print "ID["i"]="trim($8)}

开头的功能是修剪任何字段的前导或尾随空格。我根据等号分隔符拆分记录,并根据冒号":"性格FNR是我们正在查看的当前记录编号的gawk的内部变量。由于输出显然以等号条开始,所以第一条记录是空的,所以我使用FNR>1作为排除它的条件。然后我有了gawk打印代码,这些代码将成为bash的数组赋值。在您的示例中,这应该是gawk的输出:

$ gawk -f timemachine_variables.awk testdata.txt
Name[1]=USB HDD
Kind[1]=Local
Mount_Point[1]=/Volumes/USB HDD
ID[1]=317BD93D-7D90-494C-9D5F-9013B25D1345
Name[2]=TM TEST
Kind[2]=Local
Mount_Point[2]=/Volumes/TM TEST
ID[2]=4648083B-2A11-42BC-A8E0-D95917053D27

在BASH脚本中,从gawk脚本的输出中声明数组:

$ declare $(gawk -f timemachine_variables.awk testdata.txt)

现在每个驱动器都应该有BASH阵列:

$ echo ${ID[2]}
4648083B-2A11-42BC-A8E0-D95917053D27

更新:我发布的原始awk脚本在Mac上不起作用,因为BSD awk不支持多字符分隔符。我把它留在这里是因为它适用于gawk,比较这两个脚本可能会帮助其他正在寻找在BSD awk中实现多字符分隔符行为的方法的人。

我没有更改行末尾的默认记录分隔符,而是将我自己的计数器I设置为0,然后每次整个记录以一个或多个等号开始和结束时递增。由于awk现在将每一行视为其自己的记录,并且字段分隔符仍然是":&";,我们试图匹配的名称总是在$1中,值总是在$2中。

function ltrim(s) { sub(/^[ trn]+/, "", s); return s }
function rtrim(s) { sub(/[ trn]+$/, "", s); return s }
function trim(s)  { return rtrim(ltrim(s)); }
BEGIN {
FS=":";
i=0;
}
($0 ~ /^=+$/) {i++;}
($1 ~ /Name/) {print "Name["i"]="trim($2)}
($1 ~ /Kind/) {print "Kind["i"]="trim($2)}
($1 ~ /Mount Point/) {print "Mount_Point["i"]="trim($2)}
($1 ~ /ID/) {print "ID["i"]="trim($2)}

最新更新