简体   繁体   English

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

[英]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 命令:

  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不包围字符串的双引号应保留

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' 应该变成 Fo'od
  • "Fo'od" should become Fo'od “Fo'od”应该变成Fo'od
  • Fo'od should remain the same食物应该保持不变
  • 'Fo"od' should become Fo"od 'Fo"od' 应该变成 Fo"od
  • "Fo"od" should become Fo"od "Fo"od" 应该变成 Fo"od
  • Fo"od should remain the same食物应该保持不变

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 ):为了让它适用于所有请求的情况和其他一些情况,我想出了这个(用bashdash测试):

#!/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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM