使用awk提取不同字符之间的字符串

使用awk提取不同字符之间的字符串

我正在尝试编写一个 bash 函数来获取 VirtualBox 虚拟机的 UUID。我对它还很陌生,awk所以我正在努力专注于学习如何使用它来解决问题。我知道我可以使用sed甚至cut

我的“原始”输出如下VBoxManage list vms

$ VBoxManage list vms
"FreeBSD" {1aac7062-bd59-47ee-9261-2f6aa8d9ef53}
"Windows 10" {64942de7-beb9-418c-9f52-5befcb6f577b}
"High Sierra" {07f73e1a-a0c4-4190-ade1-79a2e432b4d6}
"Test Machine" {9d0953a7-ca2a-4667-8c5b-1a9f550b2956}

我想要的输出是获取特定虚拟机的 UUID。在这种情况下使用“测试机”,我正在寻找9d0953a7-ca2a-4667-8c5b-1a9f550b2956(没有括号{}

经过大量的搜索和测试,我想出了

$ VBoxManage list vms | awk '/Test Machine/{ sub("{" ,""); sub("}", "");  print $3 }'

9d0953a7-ca2a-4667-8c5b-1a9f550b2956 

它有效,但我必须使用sub命令来提取它。


我的问题是,有没有办法简化代换操作的一部分带有or类型运算符,这样我就不必使用两个sub命令?

例如,如果我尝试awk '/Test Machine/{ sub("{" || "}", ""); print $3'它不起作用 - 它会打印整个字段,包括括号。

 {9d0953a7-ca2a-4667-8c5b-1a9f550b2956}

有没有更好的方法来提取该字符串?

答案1

awk 中的 -F 字段分隔符。这里我们使用 2 个字段分隔符。 (两者任一 } )

VBoxManage list vms | awk -F"[{}]" '/Test Machine/{print $2}' 

答案2

其他方式。

VBoxManage list vms | awk -F ' ' '{print substr($2, 2, length($2) - 2)}'

用空格分隔字段

awk -F ' '

打印第二列,删除第一个{和最后}一个字符

'{print substr($2, 2, length($2) - 2)}'

答案3

With Gnu grep (uses Perl-stye regex):

grep -Po "(?<={)[a-f0-9-]+(?=})" 

...换句话说,任何十六进制数字和短划线的序列,出现在左大括号之后,紧随其后的是右大括号。

使用简单的 grep

grep -Eo "([a-f0-9-]+-){4}[a-f0-9-]+"

...即,5组由破折号分隔的十六进制数字。

答案4

$ VBoxManage showvminfo 'Test Machine' --machinereadable | sed -n '/^UUID=/{ s///; s/"//gp; }'
1ce7ffef-8faa-4138-9b92-466698762f62

它不使用list vms子命令,而是使用子命令showvminfo,它获取特定机器(此处称为 的 VM)的所有信息Test Machine。使用--machinereadable,这会以易于解析的形式输出数据。 VM UUID 将输出为

UUID="1ce7ffef-8faa-4138-9b92-466698762f62"

该命令检测到的内容sed。它删除该UUID=位和所有双引号,然后打印剩下的内容。

sed命令可以用多种不同的方式编写。例如,一种变体是,

sed -n 's/^UUID="\(.*\)"$/\1/p'

相关内容