下面是一个脚本的片段,它从一个更大的脚本中提取。 它从一个变量中删除字符串中的引号。 我使用sed来实现它,但它有效吗? 如果不是,那么什么是更有效的方法?
#!/bin/sh
opt="\"html\\test\\\""
temp=`echo $opt | sed 's/.\(.*\)/\1/' | sed 's/\(.*\)./\1/'`
echo $temp
有一种更简单、更高效的方法,使用本地 shell 前缀/后缀删除功能:
temp="${opt%\"}"
temp="${temp#\"}"
echo "$temp"
${opt%\"}
会删除后缀"
(通过反斜杠转义以防止Shell解释)。
${temp#\"}
会删除前缀"
(通过反斜杠转义以防止Shell解释)。
另一个优点是仅在有周围引号的情况下才会删除周围的引号。
顺便说一句,你的解决方案总是移除第一个和最后一个字符,无论它们是什么(当然,我相信你知道你的数据,但确保您要删除的内容总是更好的)。
使用sed:
echo "$opt" | sed -e 's/^"//' -e 's/"$//'
(根据jfgagne的建议进行改进,去除echo)
sed -e 's/^"//' -e 's/"$//' <<<"$opt"
所以它将一个前导的"
替换为空白,也会将尾随的"
替换为空白。在同一次调用中(不需要使用管道或启动另一个sed。使用-e
可以进行多个文本处理)。sed -e 's/^"//' -e 's/"$//' <<< $opt
命令可以去掉 sed 解决方案中的管道符号。 - jfg956sed
正则表达式,或将变量替换包装在类似于 case $opt in '"'*'"') ... do it ... ;; esac
的东西中。 - tripleeesed 's/^"\|"$//g'
,您可以避免多个表达式。 - tzrlkecho'"foo"'| sed 's/^"//;s/"$//'
。 - Sam如果你正在使用 jq 并试图从结果中删除引号,其他答案可能有效,但有一种更好的方法。通过使用 -r
选项,您可以输出没有引号的结果。
$ echo '{"foo": "bar"}' | jq '.foo'
"bar"
$ echo '{"foo": "bar"}' | jq -r '.foo'
bar
jq
,但请注意,如果 jq 也使用 -a
输出 ASCII 输出,则它将无法正常工作(这是 jq 方面的错误)。 - Can Poyrazoğluyq
also has -r
option: yq -r '.foo' file.yml
- Hlib Babiiecho '{"files":["http://demo.com/1.jpg","http//:demo.com/1.jpg"]}' | jq .files | jq -r 'join(" ")' | xargs wget
,当与其他工具一起使用时,-r
非常有用。 - chengziecho '"quoted"' | xargs
--> quoted
- kybxargs
将剥离所有引号。 - Metro Smurf--query
选项过来的,试试这个--output text
选项。--output tsv
。 - Eric Herlitz你只需要一次调用sed
就能完成:
$ echo "\"html\\test\\\"" | sed 's/^"\(.*\)"$/\1/'
html\test\
Bash中最简单的解决方案:
$ s='"abc"'
$ echo $s
"abc"
$ echo "${s:1:-1}"
abc
这被称为子字符串扩展(请参见Gnu Bash手册,搜索${parameter:offset:length}
)。在此示例中,它从位置1开始获取字符串s
并在倒数第二个位置结束。这是因为如果length
是负值,则将其解释为从parameter
的末尾向后运行的偏移量。最短的路径 - 尝试:
echo $opt | sed "s/\"//g"
这实际上从 opt
中删除了所有的 "
(双引号)(除了开头和结尾还会有其他双引号吗?所以实际上是相同的,而且更加简洁;-))
更新
来自于 Stripping single and double quotes in a string using bash / standard Linux commands only 的简单而优美的回答如下:
BAR=$(eval echo $BAR)
可以从 BAR
中去除引号。
=============================================================
在 hueybois 的回答基础上,我经过多次尝试后得出了以下函数:
function stripStartAndEndQuotes {
cmd="temp=\${$1%\\\"}"
eval echo $cmd
temp="${temp#\"}"
eval echo "$1=$temp"
}
如果您不想打印任何东西,可以将 evals 重定向到 /dev/null 2>&1
。$ BAR="FOO BAR"
$ echo BAR
"FOO BAR"
$ stripStartAndEndQuotes "BAR"
$ echo BAR
FOO BAR
我知道这是一个非常老的问题,但这里有另一种sed变体,可能对某些人有用。与其他一些变体不同,它只替换开头或结尾的双引号...
echo "$opt" | sed -r 's/^"|"$//g'
如果您需要匹配单引号或双引号,并且只匹配已经正确引用的字符串。 您可以使用稍微复杂一些的正则表达式...
echo $opt | sed -E "s|^(['\"])(.*)\1$|\2|g"
使用反向引用确保结尾处的引号与开头处相同。
sed "s/^\(\"\)\(.*\)\1\$/\2/g" <<<"$opt"
。这个语法只会在有匹配的引号时才移除引号。 - John Smith