コマンドを介してアクセスされる特定の文字列に対して変数置換を使用したいと思います。たとえば、クリップボードにコピーした内容には、次のようにアクセスできます。
$ xclip -o -selection clipboard
Here's a string I just copied.
変数に割り当てると、変数置換を実行できます。
$ var=$(xclip -o -selection clipboard)
$ echo $var
Here's a string I just copied.
$ echo ${var/copi/knott}
Here's a string I just knotted.
しかし、変数に代入せずに変数置換を実行する方法はありますか?概念的にはそうです。
$ echo ${$(xclip -o -selection clipboard)/copi/knott}
bash: ${$(xclip -o -selection clipboard)/copi/knott}: bad substitution
var
文字列以外の変数名が必要なため、この構文は失敗します。
答え1
答え2
はい、そうすることができます。本当にきれいではありません。それはもっと似ています待ち行列入れ子になったより。問題は、拡張パラメータの値を操作する必要があることです。パラメーターに値がないと、多くの操作を実行できません。したがって、値を割り当てることができます。しかし、拡張すると近道ではありません。
v=; echo "${v:=${0##*["$0${v:=$(xsel -bo)}"]}${v/copi/knott}}"
$0
チェーン内でパラメータ拡張を使用して隠れる分配する入れ子になった割り当て拡張内でvar値を割り当てます。外部優先 - しかし、内部的に実行されるすべてのタスクにのみ拡張されるため、話すことは困難です。しかし、内部拡張をサイレントしてから変更すると、必要なものが得られます。文字列をクリップボードにコピーした後(私はしませんでしたxclip
- ただxsel
)次のように印刷されます。
Here's a string I just knotted.
ただし、これを省略すると、何が起こるかがより明確になります$0
。
v=; echo "${v:=${v:=$(xsel -bo)}${v/copi/knott}}"
印刷:
Here's a string I just copied. Here's a string I just knotted.
...内部割り当ては変更前に行われるため、上記のように外部割り当てが優先され、内部割り当ての拡張まで拡張されます。そして内部拡張を修正しました。
もちろん、ターゲットパラメータはすでに割り当て - したがって、変数を最初に消去した場合にのみこれを実行できます。正直に割り当てるのに最も便利な時間です。
答え3
以下は、関連付けられたパラメータ置換のために一時変数割り当てをバイパスするハッキングの例です。
declare -a values=( "4: " "#1" "#2" "#3" "#4" )
declare -A arr["VALUES"]="${values[@]}"
echo -e "Original: ${arr[@]}"
"${arr[@]#*: ?}" >&/dev/null; san="${_//#/}"
echo -e "Sanitized: $san"
説明する:
arr
array の値で連想配列を初期化しますvalues
。最初の要素は値要素の数、:
フィルタリングする必要があります。と#
すべての値のプレフィックスが含まれます。
"${arr[@]#*: ?}" >&/dev/null
これは、最初に値を拡張して()arr
までの前のすべての項目をフィルタリングして合計結果を削除するパラメータのオーバーライドです。これにより、結果変数の割り当てが欠落して生じるエラーも抑制されます。'4: '
#*: ?
stdout
stderr
>&
出力()を()に割り当て、両方に割り当てる2>&1
略語です。stderr
fd2
stdout
fd1
/dev/null
ここでの秘密は、bashの特別な下線_
引数を使用して、前のコマンド(上記の最初の引数拡張操作と結果リダイレクト/dev/null
)から破棄された結果引数を2番目の引数置換にコピーすることです。ここでは、#
プレフィックス値がフィルタリングされます。
san="${_//#/}"
出力:
オリジナル: 4: #1#2#3#4
消毒:1 2 3 4
また見なさい:特殊パラメータとシェル変数
答え4
Linuxでは、ソースコマンドをパイプできます。
echo $(xclip -o -selection clipboard)/copi/knott|source /dev/stdin
それ以外のシステムでは、/dev/stdin
まず一時ファイルに書き込んでから、そのファイルに書き込む必要がありますsource
。