以下は、より大きなスクリプトからのシェルスクリプトのスニペットです。変数によって保持されている文字列から引用符を削除します。私はsedを使用してそれをやっていますが、それは効率的ですか?そうでない場合、効率的な方法は何ですか?
#!/bin/sh
opt="\"html\\test\\\""
temp=`echo $opt | sed 's/.\(.*\)/\1/' | sed 's/\(.*\)./\1/'`
echo $temp
以下は、より大きなスクリプトからのシェルスクリプトのスニペットです。変数によって保持されている文字列から引用符を削除します。私はsedを使用してそれをやっていますが、それは効率的ですか?そうでない場合、効率的な方法は何ですか?
#!/bin/sh
opt="\"html\\test\\\""
temp=`echo $opt | sed 's/.\(.*\)/\1/' | sed 's/\(.*\)./\1/'`
echo $temp
回答:
ネイティブシェルのプレフィックス/サフィックスの削除機能を使用して、より簡単で効率的な方法があります。
temp="${opt%\"}"
temp="${temp#\"}"
echo "$temp"
${opt%\"}
サフィックスを削除します"
(シェルの解釈を防ぐためにバックスラッシュでエスケープされます)。
${temp#\"}
プレフィックスを削除します"
(シェルの解釈を防ぐためにバックスラッシュでエスケープされます)。
別の利点は、周囲の引用符がある場合にのみ、周囲の引用符が削除されることです。
ところで、ソリューションでは常に最初と最後の文字が削除されます(もちろん、私はあなたがデータを知っていると確信していますが、何を削除するかを確認することは常に優れています)。
sedの使用:
echo "$opt" | sed -e 's/^"//' -e 's/"$//'
(jfgagneで示されているように、エコーを取り除く改良版)
sed -e 's/^"//' -e 's/"$//' <<<"$opt"
ですから、先頭"
を何も入れず、末尾"
を何も入れ替えません。同じ呼び出しで(別のsedをパイプして開始する必要はありません。使用-e
すると、複数のテキスト処理を行うことができます)。
sed -e 's/^"//' -e 's/"$//' <<< $opt
。
sed
正規表現を使用するか、変数置換を何かの行にラップすることができますcase $opt in '"'*'"') ... do it ... ;; esac
sed 's/^"\|"$//g'
これにより、すべての二重引用符が削除されます。
echo "${opt//\"}"
Don't remove this \" quote
ます。:-(
xargsを使用する簡単な方法があります:
> echo '"quoted"' | xargs
quoted
xargsは、コマンドが提供されていない場合、デフォルトのコマンドとしてechoを使用し、入力から引用符を取り除きます。例えばここを参照してください。
echo '"quoted"' | xargs
-> quoted
最短の方法 -試してみてください:
echo $opt | sed "s/\"//g"
それは実際にすべて"
のs(二重引用符)を削除します(opt
ただし、最初と最後以外に二重引用符が本当にあるのでしょうか?それで実際には同じことであり、はるかに簡単です;-))
jqを使用していて、結果から引用符を削除しようとしている場合、他の答えは機能しますが、より良い方法があります。この-r
オプションを使用すると、引用符なしで結果を出力できます。
$ echo '{"foo": "bar"}' | jq '.foo'
"bar"
$ echo '{"foo": "bar"}' | jq -r '.foo'
bar
jq
いますが、jqがASCII出力を出力している場合は機能しません-a
(jq側のバグです)
yq
また、持っている-r
オプション:yq -r '.foo' file.yml
更新
bash /標準のLinuxコマンドのみを使用して文字列内の単一引用符と二重引用符を取り除くことによるシンプルでエレガントな答え:
BAR=$(eval echo $BAR)
引用符を取り除きます BAR
。
================================================== ===========
hueyboisの答えに基づいて、私は多くの試行錯誤の後でこの関数を思いつきました:
function stripStartAndEndQuotes {
cmd="temp=\${$1%\\\"}"
eval echo $cmd
temp="${temp#\"}"
eval echo "$1=$temp"
}
何も印刷したくない場合は、evalをパイプして /dev/null 2>&1
。
使用法:
$ BAR="FOO BAR"
$ echo BAR
"FOO BAR"
$ stripStartAndEndQuotes "BAR"
$ echo BAR
FOO BAR
Bashの最も簡単なソリューション:
$ s='"abc"'
$ echo $s
"abc"
$ echo "${s:1:-1}"
abc
これは部分文字列展開と呼ばれます(Gnu Bashマニュアルを参照してを検索してください${parameter:offset:length}
)。この例では、部分文字列s
を位置1 から開始し、最後から2番目の位置で終了します。これはlength
、が負の値の場合、の末尾から逆方向に実行されるオフセットとして解釈されるためですparameter
。
これは、sedを使用しない最も離散的な方法です。
x='"fish"'
printf " quotes: %s\nno quotes: %s\n" "$x" "${x//\"/}"
または
echo $x
echo ${x//\"/}
出力:
quotes: "fish"
no quotes: fish
私のバージョン
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
}
関数は変数名を受け入れ、引用符を削除します。一致する先行引用符と後続引用符のペアのみが削除されます。末尾の引用がエスケープされているかどうかはチェックされません(前に\
ている自体がエスケープていない)。
私の経験では、このような汎用の文字列ユーティリティ関数(それらのライブラリがあります)は、文字列を直接操作する場合、パターンマッチングを使用しない場合、特にサブシェルを作成しない場合、または次のような外部ツールを呼び出す場合に最も効率的ですsed
、awk
または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
私はこれが非常に古い質問であることを知っていますが、これは誰かに役立つかもしれない別のsedバリエーションです。他のいくつかとは異なり、それは最初または最後の二重引用符を置き換えるだけです...
echo "$opt" | sed -r 's/^"|"$//g'
sed "s/^\(\"\)\(.*\)\1\$/\2/g" <<<"$opt"
ます。この構文は、一致するペアがある場合にのみqoutesを削除します。