Stripping single and double quotes in a string usi

2019-03-12 04:56发布

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

  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" 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

Thank you!

7条回答
孤傲高冷的网名
2楼-- · 2019-03-12 05:17

This should do it:

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

Where in.txt is:

"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:

"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
查看更多
Emotional °昔
3楼-- · 2019-03-12 05:17

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):

#!/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"
查看更多
Animai°情兽
4楼-- · 2019-03-12 05:19

You probably want to use sed...

echo $mystring | sed -s "s/^\(\(\"\(.*\)\"\)\|\('\(.*\)'\)\)\$/\\3\\5/g"
查看更多
叼着烟拽天下
5楼-- · 2019-03-12 05:28

You could use 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'.

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.

查看更多
We Are One
6楼-- · 2019-03-12 05:30
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.

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.

查看更多
时光不老,我们不散
7楼-- · 2019-03-12 05:30
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 "

查看更多
登录 后发表回答