[英]Stripping single and double quotes in a string using bash / standard Linux commands only
I'm looking for something that will translate a string as follows, using only bash / standard Linux commands:我正在寻找可以按如下方式转换字符串的内容,仅使用 bash/标准 Linux 命令:
For example:例如:
Thank you!谢谢!
This should do it:这应该这样做:
sed "s/^\([\"']\)\(.*\)\1\$/\2/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/^\([\"']\)\(.*\)\1\$/\2/g" in.txt) expected.txt
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' 在更旧的(大约 Redhat 9-ish)发行版上存在问题。
tr
is an abbreviation for 'translate', commonly used in pipes to transform input. tr
是 'translate' 的缩写,通常用于管道中以转换输入。 The -d
option simply means 'delete'. -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.大多数现代版本还包含预定义的宏来转换从上到下、从下到上、删除空白等。因此,如果你使用它,花点时间看看它还有什么作用(参见帮助输出/手册页),派上用场了。
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
.在这里,
eval echo $VAR
扩展为eval echo 'FOOD'
因为引号实际上是VAR
值的一部分。 If you were to run echo 'FOOD'
into the shell you'd get FOOD
(without the quotes).如果您将
echo 'FOOD'
运行到 shell 中,您将获得FOOD
(不带引号)。 That's what eval
does: it takes its input and runs it like a shell command.这就是
eval
所做的:它接受输入并像 shell 命令一样运行它。
⚠CODE INJECTION!
⚠代码注入!
eval
expose scripts to code injection.eval
将脚本暴露给代码注入。VAR=';ls -l' VAR=$(eval echo $VAR)
will cause execution of
ls -l
.将导致执行
ls -l
。Much more harmful codes could be injected here.
这里可以注入更多有害代码。
您可能想使用sed ...
echo $mystring | sed -s "s/^\(\(\"\(.*\)\"\)\|\('\(.*\)'\)\)\$/\\3\\5/g"
Just using Bash builtins (ie 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
Just stumbled upon this as well.也偶然发现了这一点。 For the first three test cases,
eval echo $string
works well.对于前三个测试用例,
eval echo $string
效果很好。 To get it to work for all cases requested and a few others, I came up with this (tested with bash
and dash
):为了让它适用于所有请求的情况和其他一些情况,我想出了这个(用
bash
和dash
测试):
#!/bin/sh
stripquotes() {
local firstchar="`substr "$1" 0 1`"
local len=${#1}
local ilast=$((${#1} - 1))
local lastchar="`substr "$1" $(($len - 1))`"
if [ "$firstchar" = '"' ] || [ "$firstchar" = "'" ] && [ $firstchar = $lastchar ]; then
echo "`substr "$1" 1 $(($len - 2))`"
else
echo "$1"
fi
}
# $1 = String.
# $2 = Start index.
# $3 = Length (optional). If unspecified or an empty string, the length of the
# rest of the string is used.
substr() {
local "len=$3"
[ "$len" = '' ] && len=${#1}
if ! (echo ${1:$2:$len}) 2>/dev/null; then
echo "$1" | awk "{ print(substr(\$0, $(($2 + 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"
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 "
如果它们相同并且如果它们是 ' 或 "
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.