変数の文字を置き換える方法はたくさんあります。
私が見つけた最短の方法はこれまでのところtr
です:
OUTPUT=a\'b\"c\`d_123and_a_lot_more
OUTPUT=$(echo "$OUTPUT"|tr -d "'\`\"")
echo $OUTPUT
より速い方法はありますか?そして、これは'
、"
や `自体のような引用に対して安全ですか?
どれどれ。私が思いつくことができる最短のものは、あなたのtr
ソリューションの微調整です:
OUTPUT="$(tr -d "\"\`'" <<<$OUTPUT)"
他の代替案には、これまでに示したものより短くなる可能性のある、すでに述べた変数置換が含まれます。
OUTPUT="${OUTPUT//[\'\"\`]}"
そして、もちろんsed
ですが、これは文字の面でより長いです:
OUTPUT="$(sed s/[\'\"\`]//g <<<$OUTPUT)"
最短であるか、所要時間であるかはわかりません。長さの点では、これらの2つは、それらの特定の文字を削除することになると、(または私がとにかくそれを得ることができる)できるだけ短いです。それで、どちらが最速ですか? OUTPUT
変数を例にあるものに設定してテストしましたが、数十回繰り返しました。
$ echo ${#OUTPUT}
4900
$ time tr -d "\"\`'" <<<$OUTPUT
real 0m0.002s
user 0m0.004s
sys 0m0.000s
$ time sed s/[\'\"\`]//g <<<$OUTPUT
real 0m0.005s
user 0m0.000s
sys 0m0.000s
$ time echo ${OUTPUT//[\'\"\`]}
real 0m0.027s
user 0m0.028s
sys 0m0.000s
ご覧のように、tr
が明らかに最速で、次にsed
が続きます。また、echo
を使用する方が<<<
を使用するよりも実際には少し速いようです。
$ for i in {1..10}; do
( time echo $OUTPUT | tr -d "\"\`'" > /dev/null ) 2>&1
done | grep -oP 'real.*m\K[\d.]+' | awk '{k+=$1;} END{print k/NR}';
0.0025
$ for i in {1..10}; do
( time tr -d "\"\`'" <<<$OUTPUT > /dev/null ) 2>&1
done | grep -oP 'real.*m\K[\d.]+' | awk '{k+=$1;} END{print k/NR}';
0.0029
違いはわずかなので、上記のテストを2つそれぞれについて10回実行しましたが、実際には最速のものが最初に必要だったことがわかります。
echo $OUTPUT | tr -d "\"\`'"
ただし、変数への割り当てのオーバーヘッドを考慮すると、この変更はここで、tr
の使用は単純な置換よりも少し遅くなります。
$ for i in {1..10}; do
( time OUTPUT=${OUTPUT//[\'\"\`]} ) 2>&1
done | grep -oP 'real.*m\K[\d.]+' | awk '{k+=$1;} END{print k/NR}';
0.0032
$ for i in {1..10}; do
( time OUTPUT=$(echo $OUTPUT | tr -d "\"\`'")) 2>&1
done | grep -oP 'real.*m\K[\d.]+' | awk '{k+=$1;} END{print k/NR}';
0.0044
したがって、結論として、単に結果を表示する場合はtr
を使用しますが、変数に再割り当てする場合は、シェルの文字列操作機能を使用すると、別のサブシェルを実行するオーバーヘッドを回避できるため、より高速になります。
変数置換 を使用できます:
$ OUTPUT=a\'b\"c\`d
$ echo "$OUTPUT"
a'b"c`d
その構文を使用します:${parameter//pattern/string}
は、出現するすべてのパターンを文字列に置き換えます。
$ echo "${OUTPUT//\'/x}"
axb"c`d
$ echo "${OUTPUT//\"/x}"
a'bxc`d
$ echo "${OUTPUT//\`/x}"
a'b"cxd
$ echo "${OUTPUT//[\'\"\`]/x}"
axbxcxd
Bashまたはzshでは、次のようになります。
OUTPUT="${OUTPUT//[\`\"\']/}"
ご了承ください ${VAR//PATTERN/}
は、パターンのすべてのインスタンスを削除します。詳細については bashパラメータ展開
このソリューションは外部プログラムの実行を必要としないため、短い文字列の場合は最速です。ただし、非常に長い文字列の場合はその逆が当てはまります。たとえば、テキスト操作には専用ツールを使用することをお勧めします。次に例を示します。
$ OUTPUT="$(cat /usr/src/linux/.config)"
$ time (echo $OUTPUT | OUTPUT="${OUTPUT//set/abc}")
real 0m1.766s
user 0m1.681s
sys 0m0.002s
$ time (echo $OUTPUT | sed s/set/abc/g >/dev/null)
real 0m0.094s
user 0m0.078s
sys 0m0.006s