Shell脚本 - 从变量中删除第一个和最后一个引号(“)

时间:2012-03-16 07:14:37

标签: string bash shell unix sed

以下是来自较大脚本的shell脚本片段。它从变量保存的字符串中删除引号。我是用sed做的,效率高吗?如果不是那么有效的方法是什么?

#!/bin/sh

opt="\"html\\test\\\""
temp=`echo $opt | sed 's/.\(.*\)/\1/' | sed 's/\(.*\)./\1/'`
echo $temp

16 个答案:

答案 0 :(得分:205)

使用tr删除":

 echo "$opt" | tr -d '"'

注意:这将删除所有双引号,而不仅仅是前导和尾随。

答案 1 :(得分:190)

使用本机shell前缀/后缀删除功能更简单有效:

temp="${opt%\"}"
temp="${temp#\"}"
echo "$temp"

$ {opt%\“}将删除后缀”(使用反斜杠进行转义以防止shell解释)

$ {temp#\“}将删除前缀”(使用反斜杠进行转义以防止shell解释)

另一个优点是,只有存在周围的引号时才会删除周围的引号。

顺便说一句,你的解决方案总是删除第一个和最后一个角色,无论它们是什么(当然,我确定你知道你的数据,但最好还是确定你要删除的东西)。

使用sed:

echo "$opt" | sed -e 's/^"//' -e 's/"$//'

(改进版,如jfgagne所示,摆脱回声)

sed -e 's/^"//' -e 's/"$//' <<<"$opt"

所以它取而代之的是“没有任何东西,并且没有任何东西”。在同一个调用中(不需要管道并启动另一个sed,使用-e可以进行多个文本处理)。

答案 2 :(得分:32)

如果您使用jq并尝试从结果中删除引号,则其他答案也可以使用,但是有更好的方法。通过使用-r选项,您可以输出不带引号的结果。

$ echo '{"foo": "bar"}' | jq '.foo'
"bar"

$ echo '{"foo": "bar"}' | jq -r '.foo'
bar

答案 3 :(得分:29)

这将删除所有双引号。

echo "${opt//\"}"

答案 4 :(得分:17)

只需拨打一次sed

,即可完成此操作
$ echo "\"html\\test\\\"" | sed 's/^"\(.*\)"$/\1/'
html\test\

答案 5 :(得分:17)

使用 xargs 的一种直接方法:

> echo '"quoted"' | xargs
quoted
如果没有提供命令并且

xargs 使用echo作为默认命令,并且从输入中去除引号,请参见例如here

答案 6 :(得分:15)

最短路径 - 尝试:

echo $opt | sed "s/\"//g"

它实际上删除了opt中的所有“(双引号)”(除了在开头和结尾之外,真的会有更多的双引号吗?所以,它实际上是同样的东西,还有更多简短; - ))

答案 7 :(得分:8)

<强>更新

来自https://stackoverflow.com/a/24358387/1161743的简单而优雅的回答:

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

答案 8 :(得分:6)

这不是不使用sed的最离散的方式吗?

x='"fish"'
printf "   quotes: %s\nno quotes:  %s\n" "$x" "${x//\"/}"

OR

echo $x
echo ${x//\"/}

输出:

   quotes: "fish"
no quotes:  fish

我是从Source

得到的

答案 9 :(得分:4)

我知道这是一个非常老的问题,但这是另一个sed变体,可能对某人有用。不同于其他一些,它只替换开头或结尾的双引号...

echo "$opt" | sed -r 's/^"|"$//g'

答案 10 :(得分:2)

如果您来这里是为了 aws cli --query,请尝试 --output text

答案 11 :(得分:1)

还有另一种方法。喜欢:

echo ${opt:1:-1}

答案 12 :(得分:1)

在Bash中,我将使用以下单行代码:

[[ "${str}" == \"*\" || "${str}" == \'*\' ]] && str="${str:1:-1}"

这将删除周围的引号(单引号和双引号),同时保持字符串内的引号字符完整无缺。另外,如果只有一个前导引号或只有一个尾随引号(通常是您在我的经验中想要的),它将不会做任何事情。

包装在功能中:

#!/usr/bin/env bash

# Strip surrounding quotes from string [$1: variable name]
function strip_quotes() {
    local -n var="$1"
    [[ "${var}" == \"*\" || "${var}" == \'*\' ]] && var="${var:1:-1}"
}

str="$*"
echo "Before: ${str}"
strip_quotes str
echo "After:  ${str}"

答案 13 :(得分:0)

我的版本

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,或者调用任何外部字符串sedawkgrep等工具。

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

答案 14 :(得分:0)

最简单的解决方案:

$ s='"abc"'
$ echo $s
"abc"
$ echo "${s:1:-1}"
abc

答案 15 :(得分:0)

如果由于Makefile保留引号而试图删除引号,请尝试以下操作:

$(subst $\",,$(YOUR_VARIABLE))

基于另一个答案:associative property