web-dev-qa-db-ja.com

シェルスクリプト - 変数から最初と最後の引用符( ")を削除します

以下は大きなスクリプトからのシェルスクリプトの断片です。変数によって保持されている文字列から引用符を削除します。私はsedを使ってやっています、効率的ですか?そうでない場合、それでは効率的な方法は何ですか?

#!/bin/sh

opt="\"html\\test\\\""
temp=`echo $opt | sed 's/.\(.*\)/\1/' | sed 's/\(.*\)./\1/'`
echo $temp
164
user1263746

ネイティブのシェルプレフィックス/サフィックス削除機能を使用した、よりシンプルで効率的な方法があります。

temp="${opt%\"}"
temp="${temp#\"}"
echo "$temp"

$ {opt%\ "}は接尾辞を削除します"(シェルの解釈を防ぐためにバックスラッシュでエスケープします)

$ {temp#\ "}は接頭辞を削除します"(シェルの解釈を防ぐためにバックスラッシュでエスケープします)

もう1つの利点は、周囲の引用符がある場合にのみ周囲の引用符を削除することです。

ところで、あなたの解決策は、最初と最後の文字を取り除きます(もちろん、あなたのデータを知っていると確信していますが、あなたが取り除くものを確かめることは常により良いです)。

Sedを使う:

echo "$opt" | sed -e 's/^"//' -e 's/"$//'

(jfgagneで示されるように、エコーを取り除いた改良版)

sed -e 's/^"//' -e 's/"$//' <<<"$opt"

それで、それは「何もないで、そして後ろに」先行することも何もしないで置き換えます。同じ呼び出しで(パイプを使用して別のsedを起動する必要はありません。-eを使用すると、複数のテキスト処理を実行できます)。

193
huelbois

削除するにはtrを使用してください。

 echo "$opt" | tr -d '"'

注:これは、先頭と末尾だけでなく、すべての二重引用符を削除します。

208
wieczorek1990

これにより、二重引用符がすべて削除されます。

echo "${opt//\"}"
29
Steven Penny

sedを1回呼び出すだけでそれを実行できます。

$ echo "\"html\\test\\\"" | sed 's/^"\(.*\)"$/\1/'
html\test\
17

xargsを使う簡単な方法があります。

> echo '"quoted"' | xargs
quoted

xargsは、コマンドが指定されていない場合はデフォルトのコマンドとしてechoを使用し、入力から引用符を削除します。 ここ

17
user1587520

最短の回避策 - 試してみてください。

echo $opt | sed "s/\"//g"

実際にはoptからすべての "(二重引用符)が削除されます(ただし、最初と最後以外に二重引用符がもう1つ追加されることになるのでしょうか。

15
Dr.Kameleon

更新

https://stackoverflow.com/a/24358387/116174 からのシンプルでエレガントな答え

BAR=$(eval echo $BAR)BARから引用符を取り除きます。

=================================================== ===========

Hueyboisの答えに基づいて、私は多くの試行錯誤の後にこの機能を思いついた。

function stripStartAndEndQuotes {
    cmd="temp=\${$1%\\\"}"
    eval echo $cmd
    temp="${temp#\"}"
    eval echo "$1=$temp"
}

何もプリントアウトしたくない場合は、evalsを/dev/null 2>&1に渡すことができます。

使用法:

$ BAR="FOO BAR"
$ echo BAR
"FOO BAR"
$ stripStartAndEndQuotes "BAR"
$ echo BAR
FOO BAR
8
Jonathan Lin

これはsedを使用しないで最も離散的な方法ではないでしょうか。

x='"fish"'
printf "   quotes: %s\nno quotes:  %s\n" "$x" "${x//\"/}"

OR

echo $x
echo ${x//\"/}

出力:

   quotes: "fish"
no quotes:  fish

出典 から入手しました

6
nimig18

最も簡単な解決策:

$ s='"abc"'
$ echo $s
"abc"
$ echo "${s:1:-1}"
abc
0

私のバージョン

strip_quotes() {
    while [[ $# -gt 0 ]]; do
        local value=${!1}
        local len=${#value}
        [[ ${value:0:1} == \" && ${value:$len-1:1} == \" ]] && declare -g $1="${value:1:$len-2}"
        shift
    done
}

この関数は変数名を受け入れ、引用符をその場で削除します。先頭と末尾の引用符の一致ペアのみが削除されます。末尾の引用符がエスケープされているかどうかはチェックされません(それ自体はエスケープされていない\が先行します)。

私の経験では、このような汎用の文字列ユーティリティ関数(私はそれらのライブラリを持っています)は、文字列を直接操作するとき、パターンマッチングを使わない、特にサブシェルを作成しないとき、またはsedawkまたはgrep

var1="\"test \\ \" end \""
var2=test
var3=\"test
var4=test\"
echo before:
for i in var{1,2,3,4}; do
    echo $i="${!i}"
done
strip_quotes var{1,2,3,4}
echo
echo after:
for i in var{1,2,3,4}; do
    echo $i="${!i}"
done
0
Gene Pavlovsky