剥单双引号中的字符串中使用bash/标准的Linux的命令只
题
我在找东西,将翻译成一串如下,只使用bash/标准的Linux命令:
- 单一的报价周围的一串应该被删除
- 双报价周围的一串应该被删除
- 引号字符串中应保持相同
- 串无与伦比周围的的报价应该保持相同
- 单一的报价,这并不围绕串应保持
- 双引号,不要围绕串应保持
例如:
- "食品"应该成为食物
- "食品"应该成为食物
- 粮食仍应是相同的
- '食品"应该保持相同
- "食物'应该保持相同
- '为'od'应该成为Fo'od
- "Fo'od"应该成为Fo'od
- Fo'od应保持相同
- 'Fo"od'应该成为Fo"od
- "Fo"od"应该成为Fo"od
- Fo"od应保持相同
谢谢你!
解决方案
这应该这样做:
sed "s/^\([\"']\)\(.*\)\1\$/\2/g" in.txt
哪里in.txt 为:
"Fo'od'
'Food'
"Food"
"Fo"od'
Food
'Food"
"Food'
'Fo'od'
"Fo'od"
Fo'od
'Fo"od'
"Fo"od"
Fo"od
和expected.txt 为:
"Fo'od'
Food
Food
"Fo"od'
Food
'Food"
"Food'
Fo'od
Fo'od
Fo'od
Fo"od
Fo"od
Fo"od
你可以检查他们的比赛有:
diff -s <(sed "s/^\([\"']\)\(.*\)\1\$/\2/g" in.txt) expected.txt
其他提示
你可以用 tr
:
echo "$string" | tr -d 'chars to delete'
...还工作,然而'tr'是已知会出现问题上的老得多(大约Redhat9-ish)分发。 tr
是的缩写"翻译",常用于管道转换输入。的 -d
选择只是意味着"删除"。
最现代的版本也包含预先定义的宏改变上降低,降低到上,杀死白的空间,等等。因此,如果使用它,采取第二捅还有什么它不会(见的帮助下输出/人页),就派上用场了。
VAR="'FOOD'"
VAR=$(eval echo $VAR)
说明:由于报价是已经了解的外壳可以要求壳体评估的一个命令只是回声报串,同样的方式,它不会当你的类型它自己。
在这里, eval echo $VAR
膨胀 eval echo 'FOOD'
因为报价均为实际价值的一部分 VAR
.如果你要运行 echo 'FOOD'
成壳你会得到 FOOD
(没有引号).那是什么 eval
不:它需要其输入和运行这样一个壳的命令。
这两个英语希腊代码注射!
eval
让脚本代码注射。VAR=';ls -l' VAR=$(eval echo $VAR)
会引起执行的
ls -l
.更为有害的代码可以被注射在这里。
你可能想要使用 sed...
echo $mystring | sed -s "s/^\(\(\"\(.*\)\"\)\|\('\(.*\)'\)\)\$/\\3\\5/g"
只是用来砸内置(即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
另一个例子砸参数膨胀见:
只是偶然发现了这个。第三个测试案例, eval echo $string
运作良好。得到它的工作对于所有情况下要求和其他几个人,我想出了这个(过测试 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)"
它不处理边缘的情况非常好,(例如一个空string),但它将作为一个起点。它通过条的前面和后面的性格如果他们是相同的,如果他们是'或"
不隶属于 StackOverflow