仅使用 bash/标准 Linux 命令去除字符串中的单引号和双引号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/758031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:06:39  来源:igfitidea点击:

Stripping single and double quotes in a string using bash / standard Linux commands only

linuxbashquotesquoting

提问by richq

I'm looking for something that will translate a string as follows, using only bash / standard Linux commands:

我正在寻找可以按如下方式转换字符串的内容,仅使用 bash/标准 Linux 命令:

  1. Single-quotes surrounding a string should be removed
  2. Double-quotes surrounding a string should be removed
  3. Unquoted strings should remain the same
  4. Strings with unmatched surrounding quotes should remain the same
  5. Single-quotes that don't surround the string should remain
  6. Double-quotes that don't surround the string should remain
  1. 应删除围绕字符串的单引号
  2. 应该删除围绕字符串的双引号
  3. 未加引号的字符串应保持不变
  4. 带有不匹配引号的字符串应保持不变
  5. 不围绕字符串的单引号应保留
  6. 不包围字符串的双引号应保留

For example:

例如:

  • 'Food' should become Food
  • "Food" should become Food
  • Food should remain the same
  • 'Food" should remain the same
  • "Food' should remain the same
  • 'Fo'od' should become Fo'od
  • "Fo'od" should become Fo'od
  • Fo'od should remain the same
  • 'Fo"od' should become Fo"od
  • "Fo"od" should become Fo"od
  • Fo"od should remain the same
  • “食物”应该变成食物
  • “食物”应该变成食物
  • 食物应该保持不变
  • “食物”应该保持不变
  • “食物”应该保持不变
  • 'Fo'od' 应该变成 Fo'od
  • “Fo'od”应该变成Fo'od
  • 食物应该保持不变
  • 'Fo"od' 应该变成 Fo"od
  • "Fo"od" 应该变成 Fo"od
  • 食物应该保持不变

Thank you!

谢谢!

回答by richq

This should do it:

这应该这样做:

sed "s/^\([\"']\)\(.*\)$//g" in.txt

Where in.txt is:

其中 in.txt 是:

"Fo'od'
'Food'
"Food"
"Fo"od'
Food
'Food"
"Food'
'Fo'od'
"Fo'od"
Fo'od
'Fo"od'
"Fo"od"
Fo"od

And expected.txt is:

而expected.txt是:

"Fo'od'
Food
Food
"Fo"od'
Food
'Food"
"Food'
Fo'od
Fo'od
Fo'od
Fo"od
Fo"od
Fo"od

You can check they match with:

您可以检查它们是否匹配:

diff -s <(sed "s/^\([\"']\)\(.*\)$//g" in.txt) expected.txt

回答by Tim Post

You could use tr:

你可以使用tr

echo "$string" | tr -d 'chars to delete' 

... also works, however 'tr' is known to be problematic on much older (circa Redhat 9-ish) distributions. tris an abbreviation for 'translate', commonly used in pipes to transform input. The -doption simply means 'delete'.

...也有效,但是众所周知,'tr' 在更旧的(大约 Redhat 9-ish)发行版上存在问题。tr是 'translate' 的缩写,通常用于管道以转换输入。该-d选项仅表示“删除”。

Most modern versions also contain predefined macros to transform upper to lower, lower to upper, kill white space, etc. Hence, if you use it, take a second to poke at what else it does (see the help output / man page), comes in handy.

大多数现代版本还包含预定义的宏来转换从上到下、从下到上、删除空白等。因此,如果你使用它,花点时间看看它还有什么作用(参见帮助输出/手册页),派上用场了。

回答by user3766095

VAR="'FOOD'"

VAR=$(eval echo $VAR)

Explanation: Since quotes are already understood by the shell you can ask the shell to evaluate a command that just echos the quoted string, the same way it does when you type it yourself.

说明:由于 shell 已经理解引号,因此您可以要求 shell 评估一个只回显带引号的字符串的命令,就像您自己键入时一样。

Here, eval echo $VARexpands to eval echo 'FOOD'because the quotes are actually part of the value of VAR. If you were to run echo 'FOOD'into the shell you'd get FOOD(without the quotes). That's what evaldoes: it takes its input and runs it like a shell command.

在这里,eval echo $VAR扩展为eval echo 'FOOD'因为引号实际上是 的值的一部分VAR。如果您遇到echo 'FOOD'shell,您会得到FOOD(没有引号)。这就是eval它的作用:它接受输入并像 shell 命令一样运行它。

?CODE INJECTION!

evalexpose scripts to code injection.

VAR=';ls -l'

VAR=$(eval echo $VAR)

will cause execution of ls -l.

Much more harmful codes could be injected here.

?代码注入!

eval将脚本暴露给代码注入。

VAR=';ls -l'

VAR=$(eval echo $VAR)

将导致ls -l.

这里可以注入更多有害代码。

回答by Varkhan

You probably want to use sed...

您可能想使用sed...

echo $mystring | sed -s "s/^\(\(\"\(.*\)\"\)\|\('\(.*\)'\)\)$/\3\5/g"

回答by Varkhan

Just using Bash builtins (i.e. Bash parameter expansion):

仅使用 Bash 内置函数(即 Bash 参数扩展):

IFS=' ' 

food_strings=( "'Food'" '"Food"' Food "'Food\"" "\"Food'" "'Fo'od'" "\"Fo'od\"" "Fo'od" "'Fo\"od'" '"Fo"od"' 'Fo"od'  )  

for food in ${food_strings[@]}; do 

   [[ "${food#\'}" != "$food" ]] && [[ "${food%\'}" != "$food" ]] && { food="${food#\'}"; food="${food%\'}"; } 

   [[ "${food#\"}" != "$food" ]] && [[ "${food%\"}" != "$food" ]] && { food="${food#\"}"; food="${food%\"}"; } 

   echo "$food"

done 

For yet another example of Bash parameter expansion see:

有关 Bash 参数扩展的另一个示例,请参见:

http://codesnippets.joyent.com/posts/show/1816

http://codesnippets.joyent.com/posts/show/1816

回答by Jelle Geerts

Just stumbled upon this as well. For the first three test cases, eval echo $stringworks well. To get it to work for all cases requested and a few others, I came up with this (tested with bashand dash):

也偶然发现了这一点。对于前三个测试用例,eval echo $string效果很好。为了让它适用于所有请求的情况和其他一些情况,我想出了这个(用bash和测试dash):

#!/bin/sh

stripquotes() {
    local firstchar="`substr "" 0 1`"
    local len=${#1}
    local ilast=$((${#1} - 1))
    local lastchar="`substr "" $(($len - 1))`"
    if [ "$firstchar" = '"' ] || [ "$firstchar" = "'" ] && [ $firstchar = $lastchar ]; then
        echo "`substr "" 1 $(($len - 2))`"
    else
        echo ""
    fi
}

#  = String.
#  = Start index.
#  = Length (optional). If unspecified or an empty string, the length of the
#      rest of the string is used.
substr() {
    local "len="
    [ "$len" = '' ] && len=${#1}
    if ! (echo ${1::$len}) 2>/dev/null; then
        echo "" | awk "{ print(substr($0, $(( + 1)), $len)) }"
    fi
}

var="'Food'"
stripquotes "$var"

var='"Food"'
stripquotes "$var"

var=Food
stripquotes "$var"

var=\'Food\"
stripquotes "$var"

var=\"Food\'
stripquotes "$var"

var="'Fo'od'"
stripquotes "$var"

var="\"Fo'od\""
stripquotes "$var"

var="Fo'od"
stripquotes "$var"

var="'Fo\"od'"
stripquotes "$var"

var="\"Fo\"od\""
stripquotes "$var"

var="Fo\"od"
stripquotes "$var"

# A string with whitespace should work too.
var="'F\"o 'o o o' o\"d'"
stripquotes "$var"

# Strings that start and end with the same character that isn't a quote or
# doublequote should stay the same.
var="TEST"
stripquotes "$var"

# An empty string should not cause errors.
var=
stripquotes "$var"

# Strings of length 2 that begin and end with a quote or doublequote should not
# cause errors.
var="''"
stripquotes "$var"
var='""'
stripquotes "$var"

回答by cobbal

python -c "import sys;a=sys.stdin.read();a=a.strip();print (a[1:-1] if a[0]==a[-1] and a[0] in \"'\\"\" else a)"

it doesn't handle edge cases extremely well (such as an empty string), but it will serve as a starting point. It works by striping the front and back character if they are the same and if they are ' or "

它不能很好地处理边缘情况(例如空字符串),但它可以作为起点。如果它们相同并且如果它们是 ' 或 "