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

use*_*746 188 unix string bash shell sed

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

#!/bin/sh

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

wie*_*990 239

使用tr删除":

 echo "$opt" | tr -d '"'
Run Code Online (Sandbox Code Playgroud)

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

  • 这不是OP要求的,因为它也删除了所有引号,而不仅仅是前导和尾随引号. (15认同)
  • 虽然没有明确回答OP,但这对我来说是因为在"/ path/file-name"的开头和结尾只有双引号.没有嵌入双引号.+1 (15认同)
  • 这个解决方案将成为很多人想要的.在许多情况下,脚本可以轻松地将可操作数据下移到由引号括起来的字符串. (5认同)
  • 优雅,使我免于更多的尝试错误调试时间。谢谢。 (2认同)

hue*_*ois 229

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

temp="${opt%\"}"
temp="${temp#\"}"
echo "$temp"
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

使用sed:

echo "$opt" | sed -e 's/^"//' -e 's/"$//'
Run Code Online (Sandbox Code Playgroud)

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

sed -e 's/^"//' -e 's/"$//' <<<"$opt"
Run Code Online (Sandbox Code Playgroud)

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

  • 您可以使用`sed -e'/ ^"//'-e's /"$ //'<<< $ opt`摆脱sed解决方案中的管道. (13认同)
  • 您可以通过使用 `sed 's/^"\|"$//g'` 来避免多个表达式 (4认同)
  • @jsears 嗯?如果有的话,这会特别从头开始修剪一个,如果有的话,会从末尾修剪一个。如果您不想删除,除非两者都存在;是的,可以使用单个 `sed` 正则表达式,或者可以将变量替换包装在 `case $opt in '"'*'"') 行中 ... 这样做 ... ;; 埃萨克` (2认同)

kil*_*joy 78

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

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

$ echo '{"foo": "bar"}' | jq -r '.foo'
bar
Run Code Online (Sandbox Code Playgroud)

  • `yq` 还有 `-r` 选项:`yq -r '.foo' file.yml` (2认同)

Jeh*_*Ahn 56

如果您从 AWS CLI 来到这里--query,请尝试此操作。--output text

  • 对于 azure cli 使用 `--output tsv` (7认同)
  • 哈哈哈。这正是我想要的 (3认同)
  • 我是从 AWS CLI 来到这里的,如果您将 CLI 的输出与 jq 一起使用,则可以使用选项 -r 来读取原始字符串。例如:aws codeartifact get-authorization-token --domain ${CODEARTIFACT_DOMAIN} | jq -r '.authorizationToken' (3认同)
  • 完全来自 aws cli --query。谢谢! (2认同)

小智 31

这将删除所有双引号.

echo "${opt//\"}"
Run Code Online (Sandbox Code Playgroud)


use*_*520 24

使用xargs有一种直接的方式:

> echo '"quoted"' | xargs
quoted
Run Code Online (Sandbox Code Playgroud)

如果没有提供命令,xargs使用echo作为默认命令,并从输入中删除引号,请参见此处

  • 这有效,但仅适用于字符串中偶数个引号。如果存在奇数,则会产生错误。 (2认同)
  • 最简单最优雅!谢谢。 (2认同)
  • 为我工作,通过 terraform 使用。 (2认同)
  • **如果**预期值只有开始/结束引号,这是最好的解决方案。否则,“xargs”将删除所有引号。 (2认同)

Som*_*ude 19

只需拨打一次电话即可完成sed:

$ echo "\"html\\test\\\"" | sed 's/^"\(.*\)"$/\1/'
html\test\
Run Code Online (Sandbox Code Playgroud)

  • +1仅用于处理最外面的引号 (2认同)

Dr.*_*eon 17

最短的路 - 尝试:

echo $opt | sed "s/\"//g"
Run Code Online (Sandbox Code Playgroud)

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

  • 如果你想删除所有双引号,那么最好使用:"$ {opt // \"/}".没有管道,没有子壳...并且要注意如果你在opt中有空格,你可能会松动总是引用变量,如:echo"$ opt" (4认同)

Kir*_*jan 14

Linux=`cat /etc/os-release | grep "ID" | head -1 | awk -F= '{ print $2 }'`

echo $Linux
Output:
"amzn"
Run Code Online (Sandbox Code Playgroud)

从变量中删除双引号的最简单方法是

Linux=`echo "$Linux" | tr -d '"'` 
Run Code Online (Sandbox Code Playgroud)
Linux=$(eval echo $Linux)
Run Code Online (Sandbox Code Playgroud)
Linux=`echo ${Linux//\"/}`
Run Code Online (Sandbox Code Playgroud)
Linux=`echo $Linux | xargs`
Run Code Online (Sandbox Code Playgroud)

All 提供不带双引号的输出:

回显$Linux

亚马逊


Jon*_*Lin 9

更新

来自/sf/answers/1705087121/的简单而优雅的答案:

BAR=$(eval echo $BAR)剥离报价BAR.

================================================== ===========

根据hueybois的回答,经过多次试验和错误,我想出了这个功能:

function stripStartAndEndQuotes {
    cmd="temp=\${$1%\\\"}"
    eval echo $cmd
    temp="${temp#\"}"
    eval echo "$1=$temp"
}
Run Code Online (Sandbox Code Playgroud)

如果你不想要打印任何东西,你可以将这些遗言送到/dev/null 2>&1.

用法:

$ BAR="FOO BAR"
$ echo BAR
"FOO BAR"
$ stripStartAndEndQuotes "BAR"
$ echo BAR
FOO BAR
Run Code Online (Sandbox Code Playgroud)

  • 虽然我真的很喜欢简单和优雅,但我认为值得注意的是 eval 不只是做双引号修剪,而是实际上作为一行代码进行评估。因此,当 BAR 包含可由 shell 替代的其他序列(例如 BAR=\'abc\' 或 BAR=ab\'c 或 BAR=a\$b,或 BAR=a\$\( ls \\*\) ) (3认同)

Max*_*xim 8

在 Bash 中,您可以使用以下一行:

[[ "${var}" == \"*\" || "${var}" == \'*\' ]] && var="${var:1:-1}"
Run Code Online (Sandbox Code Playgroud)

这将从存储的字符串中删除周围的引号(单引号和双引号)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}"
Run Code Online (Sandbox Code Playgroud)


Hir*_*ist 7

最简单的解决方案bash

$ s='"abc"'
$ echo $s
"abc"
$ echo "${s:1:-1}"
abc
Run Code Online (Sandbox Code Playgroud)

这称为子字符串扩展(请参阅Gnu Bash手册并搜索${parameter:offset:length})。在此示例中,它从子字符串s开始于位置1到结束于倒数第二个位置。这是由于以下事实:如果length为负值,则将其解释为相对于末尾的向后偏移parameter


use*_*825 7

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

echo "$opt" | sed -r 's/^"|"$//g'
Run Code Online (Sandbox Code Playgroud)


nim*_*g18 6

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

x='"fish"'
printf "   quotes: %s\nno quotes:  %s\n" "$x" "${x//\"/}"
Run Code Online (Sandbox Code Playgroud)

要么

echo $x
echo ${x//\"/}
Run Code Online (Sandbox Code Playgroud)

输出:

   quotes: "fish"
no quotes:  fish
Run Code Online (Sandbox Code Playgroud)

我从Source得到了这个