如何从命令输出中提取带引号的字符串的内容?


Answers:


34

使用grep + sed

这将解析这两个字符串的内容:

$ grep -o '".*"' somefile | sed 's/"//g'
arch
arch2

上面寻找与模式匹配的字符串".*"。这将匹配双引号中出现的所有内容。因此grep将返回以下类型的值:

"arch"
"arch2"

管道sed将去除这些字符串中的所有双引号,从而为您提供所需的字符串。该符号sed 's/"//g'指示sed进行搜索并替换所有出现的双引号,并用\代替s/"//g。该命令s/find/replace/g在那里执行,g搜索的结尾告诉它在给定的整个字符串上全局进行搜索。

使用刚刚的sed

您还可以sed用来截断开始的双引号,保留它们之间的内容,并截去剩余的引号和之后的所有内容:

$ sed 's/^"\(.*\)".*/\1/' a
arch
arch2

其他方法

$ grep -o '".*"' somefile | tr -d '"'
arch
arch2

该命令tr可用于删除字符。在这种情况下,它将删除双引号。

$ grep -oP '(?<=").*(?=")' somefile
arch
arch2

使用grep的PCRE功能,您可以查找任何以双引号开头或以双引号结尾的子字符串,并仅报告该子字符串。


1
tr -d \"是删除引号的另一种方法。(tr通常将一组字符转换为另一组;-d告诉它只是删除它们。)
2014年

1
SLM -如果添加/address/sedsed '/^"\(arch[^"]*\)/s//\1/你只对包含该串线运营。
mikeserv 2014年

1
@mikeserv-是的,不确定拱在他的输出中是否保持一致。但是,如果是这样,那也将起作用。
slm

1
好点的slm。没有迹象表明会保持一致。抱歉。
mikeserv 2014年

2
我只是意识到尽管您sed确实应该这样做s/^"\([^"]*\)".*/\1/,以防万一在线上只有两个双引号。
mikeserv

19

那是另一项工作cut

VBoxManage list vms | cut -d \" -f2

3
非常整洁!工作原理:cut使用引号作为分隔符将每一行拆分为多个字段,然后输出字段2:字段1是第一个引号之前的空字符串,字段2是引号之间的所需字符串,而字段3是其余的线。
deltab 2014年

7

有了sed您就可以做到:

var=$(VBoxManage list vms | sed 's/^"\([^"]*\).*/\1/')

说明:

  • s/.../.../ -匹配并替换
  • ^-在行首匹配
  • \(...\) -这是一个反向参考,我们可以稍后在这里参考匹配的内容 \1
  • [^"]*-匹配任何不包含的序列"(即直到下一个"
  • .* -匹配其余部分
  • \1 -替换为后面的参考

或搭配awk

var=$(VBoxManage list vms | awk -F\" '{ print $2 }')

请注意,在现代Shell中,您也可以使用数组代替普通变量。在bash你可以这样做:

IFS=$'\n'; set -f
array=( $(VBoxManage list vms | awk -F\" '{ print $2 }') )
echo "array[0] = ${array[0]}"
echo "array[1] = ${array[1]}"

当您开始使用该变量时,这可能会更容易。


您能帮我分掉sed命令吗?
哈里斯·卡万

5

使用bash,我会写:

while read vm value; do
    case $vm in
        '"arch"') arch=$value ;;
        '"arch2"') arch2=$value ;;
    esac
done < <( VBoxManage list vms )
echo $arch
echo $arch2

5

还有一个通过grep oneliner --perl-regexp选项提供的选项,

VBoxManage list vms | grep -oP '(?<=^\")[^"]*'

说明:

(?<=^\")[^"]*->在这里使用后向。它匹配任何字符,但不匹配"零次或多次(一旦找到双引号,它将停止匹配),该字符仅在双引号之后(仅以双引号开头的行)。

通过另一个丑陋的骇客sed

$ sed '/.*\"\(.*\)\".*/ s//\1/g' file
arch
arch2

0

由于正则表达式具有贪婪模式和非贪婪模式,因此,如果您在同一行上有多个目标,则它不会像您希望的那样提取。线:

"tom" is a cat, and "jerry" is a mouse. 

目标:

tom
jerry

命令(贪婪模式):

grep -oP '".*"' name

命令(非贪婪模式):

grep -oP '".*?"' name
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.