以下是来自较大脚本的Shell脚本的片段。它从由变量保存的字符串中删除引号。我正在使用sed进行操作,但是效率高吗?如果没有,那么有效的方法是什么?
#!/bin/sh
opt="\"html\\test\\\""
temp=`echo $opt | sed 's/.\(.*\)/\1/' | sed 's/\(.*\)./\1/'`
echo $temp
以下是来自较大脚本的Shell脚本的片段。它从由变量保存的字符串中删除引号。我正在使用sed进行操作,但是效率高吗?如果没有,那么有效的方法是什么?
#!/bin/sh
opt="\"html\\test\\\""
temp=`echo $opt | sed 's/.\(.*\)/\1/' | sed 's/\(.*\)./\1/'`
echo $temp
Answers:
使用本机外壳程序前缀/后缀删除功能,有一种更简单,更有效的方法:
temp="${opt%\"}"
temp="${temp#\"}"
echo "$temp"
${opt%\"}
将删除后缀"
(使用反斜杠转义以防止解释外壳)。
${temp#\"}
将删除前缀"
(使用反斜杠转义以防止解释shell)。
另一个优点是,仅当有引号时才删除引号。
顺便说一句,您的解决方案始终会删除第一个和最后一个字符,无论它们是什么(当然,我确定您知道您的数据,但是最好确定要删除的内容)。
使用sed:
echo "$opt" | sed -e 's/^"//' -e 's/"$//'
(改进版本,如jfgagne所示,摆脱了回声)
sed -e 's/^"//' -e 's/"$//' <<<"$opt"
因此,它"
用一无所有替换了前导,也没有替换了尾随"
。在同一调用中(无需管道传输和启动另一个sed。使用-e
该文件可以进行多个文本处理)。
sed -e 's/^"//' -e 's/"$//' <<< $opt
。
sed
可以使用单个正则表达式,也可以将变量替换包装在一行中case $opt in '"'*'"') ... do it ... ;; esac
sed 's/^"\|"$//g'
这将删除所有双引号。
echo "${opt//\"}"
Don't remove this \" quote
。:-(
最短的解决方法 -尝试:
echo $opt | sed "s/\"//g"
它实际上"
从中删除了所有s(双引号)opt
(除了在开头和结尾之外,是否还会有其他双引号?所以实际上是同一件事,并且更简短;-))
如果您正在使用jq并尝试从结果中删除引号,则其他答案也可以使用,但是有更好的方法。通过使用该-r
选项,您可以输出不带引号的结果。
$ echo '{"foo": "bar"}' | jq '.foo'
"bar"
$ echo '{"foo": "bar"}' | jq -r '.foo'
bar
jq
但请注意,如果jq也输出ASCII输出-a
(这是jq侧的一个错误)
yq
还可以-r
选择:yq -r '.foo' file.yml
更新资料
一个简单而优雅的答案,仅使用bash /标准Linux命令来去除字符串中的单引号和双引号:
BAR=$(eval echo $BAR)
从中删除引号BAR
。
================================================== ===========
根据hueybois的回答,经过反复试验,我想到了这个功能:
function stripStartAndEndQuotes {
cmd="temp=\${$1%\\\"}"
eval echo $cmd
temp="${temp#\"}"
eval echo "$1=$temp"
}
如果您不想打印任何内容,则可以将评估传递到/dev/null 2>&1
。
用法:
$ BAR="FOO BAR"
$ echo BAR
"FOO BAR"
$ stripStartAndEndQuotes "BAR"
$ echo BAR
FOO BAR
Bash中最简单的解决方案:
$ s='"abc"'
$ echo $s
"abc"
$ echo "${s:1:-1}"
abc
这称为子字符串扩展(请参阅Gnu Bash手册并搜索${parameter:offset:length}
)。在此示例中,它从s
位置1开始到第二倒数第二个位置获取子字符串。这是由于以下事实:如果length
为负值,则将其解释为相对于末尾的向后偏移parameter
。
这是不使用sed的最离散的方法:
x='"fish"'
printf " quotes: %s\nno quotes: %s\n" "$x" "${x//\"/}"
要么
echo $x
echo ${x//\"/}
输出:
quotes: "fish"
no quotes: fish
我从消息来源那里得到的。
我的版本
strip_quotes() {
while [[ $# -gt 0 ]]; do
local value=${!1}
local len=${#value}
[[ ${value:0:1} == \" && ${value:$len-1:1} == \" ]] && declare -g $1="${value:1:$len-2}"
shift
done
}
该函数接受变量名,并在适当位置删除引号。它仅去除匹配的一对前导和尾随引号。它不检查尾随引号是否被转义(前面\
没有被转义的引号)。
以我的经验,像这样的通用字符串实用程序函数(我有它们的库)在直接操作字符串,不使用任何模式匹配,尤其是不创建任何子shell或调用任何外部工具(例如,sed
,awk
或grep
。
var1="\"test \\ \" end \""
var2=test
var3=\"test
var4=test\"
echo before:
for i in var{1,2,3,4}; do
echo $i="${!i}"
done
strip_quotes var{1,2,3,4}
echo
echo after:
for i in var{1,2,3,4}; do
echo $i="${!i}"
done
sed "s/^\(\"\)\(.*\)\1\$/\2/g" <<<"$opt"
。仅当存在匹配对时,此语法才会删除qoutes。