下面是一个大脚本中的shell脚本片段。它从变量持有的字符串中删除引号。我正在使用sed,但它是有效的吗?如果不是,那么什么是有效的方法?

#!/bin/sh

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

当前回答

如果你来这里是为了aws cli -query,试试这个。——输出文本

其他回答

你只需要调用一次sed就可以做到:

$ echo "\"html\\test\\\"" | sed 's/^"\(.*\)"$/\1/'
html\test\

有一个更简单、更有效的方法,使用本机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"

因此,它将开头的“nothing”替换为“nothing”,后面的“尾随”也替换为“nothing”。在同一个调用中(不需要管道和启动另一个sed)。使用-e可以进行多个文本处理)。

我的版本

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的最离散的方式:

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

Or

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

输出:

   quotes: "fish"
no quotes:  fish

我从线人那里得到的。

在Bash中,你可以使用下面的一行代码:

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

这将从存储在var中的字符串中删除周围的引号(单引号和双引号),同时保持字符串中的引号字符完整。同样,如果只有一个前引号或只有一个后引号,或者在开始/结束处有混合引号字符,这将不起任何作用。


包装在函数中:

#!/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="'hello world'"
echo "Before: ${str}"
strip_quotes str
echo "After: ${str}"