仅使用 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
Stripping single and double quotes in a string using bash / standard Linux commands only
提问by richq
I'm looking for something that will translate a string as follows, using only bash / standard Linux commands:
我正在寻找可以按如下方式转换字符串的内容,仅使用 bash/标准 Linux 命令:
- Single-quotes surrounding a string should be removed
- Double-quotes surrounding a string should be removed
- Unquoted strings should remain the same
- Strings with unmatched surrounding quotes should remain the same
- Single-quotes that don't surround the string should remain
- Double-quotes that don't surround the string should remain
- 应删除围绕字符串的单引号
- 应该删除围绕字符串的双引号
- 未加引号的字符串应保持不变
- 带有不匹配引号的字符串应保持不变
- 不围绕字符串的单引号应保留
- 不包围字符串的双引号应保留
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. tr
is an abbreviation for 'translate', commonly used in pipes to transform input. The -d
option 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 $VAR
expands 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 eval
does: 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!
eval
expose 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 参数扩展的另一个示例,请参见:
回答by Jelle Geerts
Just stumbled upon this as well. For the first three test cases, eval echo $string
works well. To get it to work for all cases requested and a few others, I came up with this (tested with bash
and 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 "
它不能很好地处理边缘情况(例如空字符串),但它可以作为起点。如果它们相同并且如果它们是 ' 或 "