提取双引号之间的字符串

提取双引号之间的字符串

我需要使用引号提取字符串。我的字符串如下。

"abcd efgh" "ijkl mnop" "qrst uvwxyz"

ijkl mnop你能帮我使用sedorgrep命令获取第二个双引号()之间的字符串吗?

换句话说,如果我说给我第一个引号中的字符串,我想要第一个字符串;如果我说第二个字符串,它应该给我第二个双引号和类似的第三个双引号之间的字符串。

答案1

我不确定你想如何输入字符串。这已经达到了您想要达到的效果,但可能需要根据字符串的输入方式进行修改:

aa() { echo $3 ; } ; aa "abcd efgh" "ijkl mnop" "qrst uvwxyz"

编辑:因此,如果它在变量中(必须用引号 " 定义):

AA="\"abcd efgh\" \"ijkl mnop\" \"qrst uvwxyz\""
echo $AA

然后:

FIRST=`echo $AA| awk -F \" '{print $2}'`
SECOND=`echo $AA| awk -F \" '{print $4}'`
THIRD=`echo $AA| awk -F \" '{print $6}'`
echo $FIRST : $SECOND : $THIRD

正如 Jasonwryan 上面指出的那样。你说,你想使用 sed,但这使它变得不必要的复杂:

FIRST=`echo $AA| sed 's/^\"\([^\"]*\)\".*/\1/'`
SECOND=`echo $AA| sed 's/^\"[^\"]*\" \"\([^\"]*\)\".*/\1/'`
THIRD=`echo $AA| sed 's/^\"[^\"]*\" \"[^\"]*\" \"\([^\"]*\)\".*/\1/'`

编辑2: 实际上可以完全不使用 sed、awk、perl,.. 仅使用 bash,使用其“read”内置函数,如下所示(echo 用于调试):

#!/bin/bash

aa() {
echo '$1'="$1"
IFS=\" read aaa FIRST bbb SECOND ccc THIRD ddd <<< "$1"
echo FIRST=$FIRST : SECOND=$SECOND : THIRD=$THIRD
}

AA="\"abcd efgh\" \"ijkl mnop\" \"qrst uvwxyz\""
echo '$AA'="$AA"
aa "$AA"

答案2

你在评论中这样说过:

上面的字符串是变量。我需要提取每个部分(第一,第二,第三)并将其存储不同的变量

所以我们就分开吧。

IFS=\"                  #set the shell's field separator
set -f                  #don't try to glob 
set -- $var             #split on $IFS
var1=$2 var2=$4 var3=$6 #yay
unset IFS               #restore something like a sane default

不过,这不会处理可能包含反斜杠转义引号的字符串。我希望这不是问题,因为我不喜欢这样做。

答案3

基于(并稍微简化)ludvik02 的sed答案:

AA='"abcd efgh" "ijkl mnop" "qrst uvwxyz"'
AA1=$(echo "$AA" | sed -r 's/^([^"]*"){1}([^"]*).*/\2/')
AA2=$(echo "$AA" | sed -r 's/^([^"]*"){3}([^"]*).*/\2/')
AA3=$(echo "$AA" | sed -r 's/^([^"]*"){5}([^"]*).*/\2/')
(Note that                        this ↑                        is different on every line.)

-r启用扩展正则表达式的选项sed。我们需要使用它,这意味着{n}n前面的正则表达式出现的次数。  ([^"]*")是一个复合(组)正则表达式,匹配除 之外的任意数量的字符",以 结尾"。示例输入字符串最多可以匹配此正则表达式六次(因为它有六个"字符);插入...s 来区分字符串之间的间隙,这些出现的情况是

"abcd efgh" ... "ijkl mnop" ... "qrst uvwxyz"
↑↑--------↑↑----↑↑--------↑↑----↑↑----------↑
1    2       3       4       5        6

匹配任何奇数(例如,三个)出现的 会消耗直到并包括第n一个(例如,第三个)"字符的所有内容,即第一个(例如,第二个)引用字符串"开头的字符。然后匹配(并分组)直到(但不包括)第th 个字符(即第二个带引号的字符串末尾的字符)的所有内容。因此该组(第二组)与第二个带引号的字符串匹配。最后,消耗输入字符串的其余部分。然后我们将整个输入行替换为第二组的值:((n+1)/2)([^"]*)(n+1)"".*\2

"abcd efgh" ... "ijkl mnop" ... "qrst uvwxyz"
↑↑--------↑↑----↑⇑=======⇑⇈≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡⇈
1    2       3
↑---------------↑⇑=======⇑⇈≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡⇈
        \1          \2          (unnamed)

相关内容