編集 - bash
$1
変数を使用しません。例では、フィールド指定子を使用しています。$1
、$2
は$3
入力awk
レコードフィールドです。残念ながら、例をあまりにも早く見て、例が混同された。
私はこれが一般的な問題だと思います。awk
プレゼンテーションツールとして使用しています。目的は、(またはすべてのツール)コマンドawk
で()スクリプトパラメータを暗示することです。awk
STDINでasとして提供されたフィールドを使用してawk
結果を生成します。識別子は$1
STDINストリームのフィールドです$2
。$3
awk
必須ソリューションA(優先概念)、例:…
#!/bin/bash -f
# script: blue.sh
#
awk -e '{ print $1 " and " $2 " silly example" ;}'
#
そして望ましい出力:
$ echo "red blue yellow" > ./blue.sh
red and blue silly example
$
おそらく代替Bを考えることができます。
#!/bin/bash -f
# script: green.sh
#
wrk="awk -e '{ print \$3 \" and \" \$2 \" variable example\" ;}' "
#
echo "work is:"
echo $wrk
echo
$wrk
そして望ましい出力:
$ echo "red blue yellow" > ./green.sh
wrk is:
awk -e '{ print $3 " and " $2 " variable example" ;}'
yellow and blue variable example
$
問題は-e
式の参照にあります。
これらの例を実装する方法はありますか?
答え1
これはおそらく」変数に保存されたコマンドをどのように実行できますか?」と言いますが、いろいろな部分で構成されていますので、お客様の状況に合わせて具体的にお答えいたします。
- コマンドを変数に保存し、その変数を使用して実行します。
- にデータを渡します
awk
。
「変数で命令を実行する」ビット
以下は、スクリプトの代替実装に関する提案です。
#!/bin/bash
wrk=( awk -v a="$3" -v b="$2"
'BEGIN { printf "%s and %s variable example\n", a, b }' )
awk -v a="$1" -v b="$2" 'BEGIN { printf "%s and %s silly example\n", a, b }'
printf 'wrk is: %s\n' "${wrk[*]}"
"${wrk[@]}"
これを実行してください:
$ ./blue.sh "red" "blue" "yellow"
red and blue silly example
wrk is: awk -v a=yellow -v b=blue BEGIN { printf "%s and %s variable example\n", a, b }
yellow and blue variable example
私がしたことはawk
コマンドを保存することでした。大量に文字列ではありません。これにより、配列内の個々の要素を配列の残りの部分とは別に個別の要素として維持しながら、正しく参照できます。たとえば、先頭の単語は、awk
配列(フルコード)の最後の項目とはawk
別の単語です。
コマンドとして使用される場合、"${wrk[@]}"
配列の各要素は別々のコマンドライン引数として使用されます(最初の要素はコマンドです)。拡張参照を使用"${wrk[@]}"
すると、各要素が個別に参照されます(使用しても${wrk[@]}
効果はありません)。
これは変数にコマンドを保存して実行する方法です。つまり、配列を使用し、配列要素と配列拡張を正しく参照していることを確認してください。
シェルスクリプト呼び出しの場合は、配列で単一の文字列生成をprintf
使用します(デフォルトでは、すべての要素はスペースで区切られています)。これは、シェルが配列を作成するときにこれらの要素を削除するため、予想される個々の要素への参照を保持しないことを意味します(同様の操作を実行するときに引用符を削除するのと同じです)。"${wrk[*]}"
wrk
a='hello world'
表示する個々の要素ごとに、wrk
次のものを使用してくださいprintf 'element: "%s"\n' "${wrk[@]}"
。これは出力されます
element: "awk"
element: "-v"
element: "a=yellow"
element: "-v"
element: "b=blue"
element: "BEGIN { printf "%s and %s variable example\n", a, b }"
この特別なケースでは、必要に応じてシェル機能を使用することもできます。
#!/bin/bash
wrk () {
awk -v a="$1" -v b="$2" 'BEGIN { printf "%s and %s variable example\n", a, b }'
}
awk -v a="$1" -v b="$2" 'BEGIN { printf "%s and %s silly example\n", a, b }'
wrk "$3" "$2"
関数のとは、$1
スクリプト$2
ではなく関数の最初と2番目のパラメータを表します。
これを実行してください:
$ ./blue.sh "red" "blue" "yellow"
red and blue silly example
yellow and blue variable example
- 特定awk
ビット
awk
コマンドラインにデータを渡すには、-v
初期化awk
変数を使用しますawk
。これはシェル拡張を介してコードに変数を注入するよりも優れていますawk
。これは、ユーザーが単純なデータではなく実行可能なコードを注入できるようにするためです(たとえば、単に$3
a;
といくつかのコードを含めることによって)。awk
望むより」awkのコマンドラインパラメータ「そしてこのサイトにも同様の質問がありますこれについて詳しく学んでください。
awk
環境変数を使用してデータを渡すこともできます。
a=$3 b=$2 awk 'BEGIN { printf "%s and %s variable example\n", ENVIRON["a"], ENVIRON["b"] }' )
または、
export a="$3"
export b="$2"
awk 'BEGIN { printf "%s and %s variable example\n", ENVIRON["a"], ENVIRON["b"] }' )
また、標準入力には読み取り可能な入力がないため、awk
単一ブロックでコードを実行しています。BEGIN
答え2
解決策を見つけましたが、結果はもともと考えていたものとはかなり異なりました。bash
コマンドで-script変数を拡張する方法が見つからなかったため、これを「構成」する必要がありました。xargs
これは、シェルが目的の操作を実行する方法に関連するさまざまな理由で不適切であることがわかりました。
実行中の例を見て、次のコードを見て、何が起こるのかを説明します。 「#(2)」などのタグで議論する領域を表示しました。
はい:
入力する...
$ svn status -qu ..
M 28637 /src/line.h
M 28637 /src/line.cpp
* 28637 /testing/CheckWindows.py
処理...
繰り返しスクリプトは2つのパラメータを使用します。
- 入力リストから実行するテンプレートまたは1つ以上のコマンド
awk
入力ストリームフィルタリングのためのいくつかのコマンド
コマンドライン:
svn status -qu .. | repeat \
'cp -v $ff /mnt/testhost/testarea/r02/$ff' \
"{ if( $1 == "M" ){ print $3; } }"
出力...
'/src/line.h' -> '/mnt/testhost/testarea/r02/src/line.h'
'/src/line.cpp' -> '/mnt/testhost/testarea/r02/src/line.cpp'
どうしたの??
- ローカルで変更されたファイルのみコピー
r02/testarea
- 明らかにフィルタリングは何でもよい
- の目的は、
repeat
フィルタリングされた入力リストから一連のコマンドを繰り返すことです。
コメント付きコード:
#!/bin/bash
# repeat.bash
function repeat
{
local -a actions=()
local DELIMITER=";"
local filter="${2}"
local cmd=""
local wrk="${1}${DELIMITER}" # (1) Template
local str=""
while [[ $wrk ]] # (2) Split-up individual commands
do
str="${wrk%%"${DELIMITER}"*}"
actions+=( "${str}" )
wrk="${wrk#*"${DELIMITER}"}"
done
echo "actions: " # (3) Debugging code
for action in "${actions[@]}"
do
echo " => \"${action}\"."
done
echo "filter => '${filter}'."
ex="${filter}" # (4) Awk instructions to
# process input stream
for ff in $(awk -e "${ex}") # (5) .
do
for action in "${actions[@]}" # (6) .
do
cmd="${action//\$\{ff\}/${ff}}" # (7) .
cmd="${cmd//\$ff/${ff}}"
${cmd} # (8) .
done
done
return
}
repeat "${@:1}" # (9) .
ノート:
- Argは
$1
コマンドテンプレートです。
*後で解析するために末尾に区切り文字を追加します。 $1
通常、複数のコマンドを使用します。入力パラメータを別々のセミコロンで区切られたコマンド文字列に分割します。- 確認のためにパラメータを印刷します。
- フィルタを
ex
変数にロードします。
* この例では、ex
フィルタのみに渡されます$2
。 - フィルタリングされた入力行によって生成された各文字列を繰り返します。
*ex
awk
選択/生成フィルタで実行されるコマンドになります。 - すべてのコマンドテンプレートを繰り返します
action
。 $ff
コマンド文字列${ff}
の拡張構文action
。- 各ファイルに対して生成された各コマンドラインを実行します
$ff
。 - スクリプトを実行するには、この関数を呼び出します。
poutの場合、パラメータをawk
テンプレート文字列に直接注入できないため、これは非常に異なります。しかし、回避策はそれほど不便ではなく、神秘的な拡張機能なしでどのように機能するかを示しています。
私はこの考えが役に立つと信じています。今動作するスニペットがあるのでとても便利だと思います。