私が作成したbashスクリプトに問題があります。 forループ内ですべてのパラメータを繰り返して、後で「eval」コマンドに入力する文字列変数を設定します。
for arg in "$*"
do
if [ $arg != $lastArg ]; then
findTarget+="-name $arg -o "
else
findTarget=$(echo $findTarget | sed 's/-o$//')
break
fi
done
問題は「$ *」で発生します。たとえば、パラメータに「* .c」と入力し、現在のフォルダにそのパターンと一致するファイルが含まれている場合、パラメータはそのファイル*.c
に展開されます。私はこれをしたくありません。findTarget
と接続しようとして-name *.c -o
います。 evalを使用し、引用符なしでは効果がないようです。これを行う方法を知っていますか(可能であれば簡単に)?注:パラメーターの総数は異なる場合があります。
以下は、スクリプトを実行する方法の例です。
$ trouver.bash *.c *.f90 someString
私のforループが終わったら、変数はfindTarget
次のようになります。-name *.c -o -name *.f90
*.c
*.f90
現在のフォルダ内のファイルと一致する場合、または一致する場合は効果がありません。
答え1
位置パラメータを繰り返す構文はfor arg do
別々です。"$*"
は最初の文字と位置引数を連結したものなので、1つの$IFS
要素だけを繰り返すことになります。
また、コマンドのパラメータリストを作成するには、find
文字列ではなく配列が必要です。そして変数を引用することを忘れないでください!
だから:
findTarget=()
or=()
for arg
do
[ "$arg" = "$lastArg" ] && break
findTarget+=("${or[@]}" -name "$arg")
or=(-o)
done
find . \( "${findTarget[@]}" \)
スクリプトを呼び出すときに必要なことに注意してください。引用する...mode*.c
それ以外の場合は、スクリプトに渡される前にシェルによって拡張されます。
trouver.bash '*.c' '*.f90' someString
対話型シェルがある場合は、zsh
ワイルドカードを無効にしてコマンドのエイリアスを定義できます。
alias trouver.bash='noglob trouver.bash'
このようにして、次のことができます。
trouver.bash *.c *.f90 someString
この球体を拡張するシェルはありません*.c
*.f90
。
答え2
"$*"
すべてのパラメータを1つの長いパラメータにリンクするには、メソッドを使用します。これを次に変更すると、引数のリストが表示され"$@"
ます。ただし、実際にfor arg in "$@"
正しいイディオムを使用する必要はありませんfor arg
。
-o
その後、新しいパラメータごとに1つを追加して使用できます${findTarget[@]+"-o "}
。
値が割り当てられていない場合はnullになり、値が割り当てられている場合はfindTarget
通常の文字列になります。最初のループ実行ではnullに縮小され、次のループではnullになります。-o
findTarget
-o
(( $# < 1 )) && echo "please provide some argument(s)" && exit 1
unset findTarget
for arg
do [[ "$arg" == "$lastArg" ]] && break
findTarget+=("${findTarget[@]+"-o "}-name $arg")
done
find . \( "${findTarget[@]}" \)
次のようにスクリプトを実行する必要があります。
$ trouver.bash '*.c' '*.f90' someString
必要に応じて、各引数はシェルによって拡張されません(二重引用符を使用してください。二重引用符は機能できますが、拡張なしで引数を保持する意図を明確に表すわけではありません)。
「一重引用符」なしでスクリプトを使用する必要がある場合は、「パス名拡張」(set -f)を削除して拡張を防ぐことができます*
。
$ ( set -f; trouver.bash *.c *.f90 someString )
これにより、()
noglobへの変更が現在実行中のシェルに影響を与えるのを防ぎます。
これは、スクリプトが結果を作成しstdout
てサブシェル内で印刷することもできるために機能します(…)
。