bashスクリプトで$ 1や$ 2などの特定の入力変数を省略しながら$ *を使用するにはどうすればよいですか?


15

例えば、

elif [[ $append = $1 ]]
then
  touch ~/directory/"$2".txt
  echo "$variable_in_question" >> ~/directory/"$2".txt

に続くすべての入力を含むテキストファイルを作成するか、すべての入力に続く"$2"既存のテキストファイルを追加する"$2"には"$variable_in_question"、4行目の代わりに何を使用しますか?

私は基本的に欲しい"$*"が、とを省略"$1""$2"ます。

回答:


32

bashパラメータ拡張を使用して範囲を指定できます。これは位置パラメータでも機能します。以下のための$3... $nそれは次のようになります。

"${@:3}" # expands to "$3" "$4" "$5" …
"${*:3}" # expands to "$3 $4 $5 …"

両方に注意し、最初の引数$@$*無視してください$0。あなたがあなたのケースでどちらを使用するのか疑問に思ったら:あなたが引用符を付けたいと思うことは非常にありそうです$@。使用しないでください$*、あなたが明示的にしない限りません引数を個別に引用されたことにしたいです。

次のように試してみることができます。

$ bash -c 'echo "${@:3}"' 0 1 2 3 4 5 6
3 4 5 6
$ echo 'echo "${@:3}"' >script_file
$ bash script_file 0 1 2 3 4 5 6
2 3 4 5 6

最初の例で$0は最初の引数が入力0されます$0が、2番目の例が示すように、スクリプトで使用される場合は代わりにスクリプト名が入力されます。スクリプトの名前bashはもちろんである、それは通常、このようなとして認識いないだけという、最初の引数-スクリプトが実行可能にし、「直接」と呼ばれるために同じことが行きます。したがって、最初の例では$0= 0$1= 1などがあり、2番目の例では$0= script_file$1= 0$2= 1などです。${@:3}で始まるすべての引数を選択し$3ます。

可能な範囲の追加例:

 # two arguments starting with the third
$ bash -c 'echo "${@:3:2}"' 0 1 2 3 4 5 6
3 4
 # every argument starting with the second to last one
 # a negative value needs either a preceding space or parentheses
$ bash -c 'echo "${@: -2}"' 0 1 2 3 4 5 6
5 6
 # two arguments starting with the fifth to last one
$ bash -c 'echo "${@:(-5):2}"' 0 1 2 3 4 5 6
2 3

参考文献:


27

shiftビルトインを使用できます:

$ help shift
shift: shift [n]
    Shift positional parameters.

    Rename the positional parameters $N+1,$N+2 ... to $1,$2 ...  If N is
    not given, it is assumed to be 1.

    Exit Status:
    Returns success unless N is negative or greater than $#.

例 与えられた

$ cat argtest.bash 
#!/bin/bash

shift 2

echo "$*"

それから

$ ./argtest.bash foo bar baz bam boo
baz bam boo

3
@Oreoplasm私は、このshiftアプローチがアクセスすることを不可能にし$1$2それらをシフトした後に言及する価値があると思います。で使用するスクリプト$2では$variable_in_question、それを変更するか、パラメータ拡張アプローチを使用する必要があります。
デザート

6
shift最初の一つ以上の引数が特別であり、それは別々の変数にそれらを選ぶことは理にかなっていたときに(良いですfoo="$1"; bar="$2";if [[ something with $1 ]];then blah blah; shift。しかし、あなたがたときに、非破壊的なアプローチとデザートの答え@他の例でいいです、まだ後の完全なリストが欲しいですまたは、より$@多くの要素がない場合、コマンドに空の引数を導入せずに、より洗練された構文を使用して、無限にではなく、限られた範囲の引数を選択する場合
Peter Cordes

13

一般に、元の引数を失うことなく、位置パラメータを配列にコピーし、配列の任意のインデックスを削除してから、配列を使用して必要なインデックスに正確に拡張できます。

たとえば、1番目、4番目、5番目を除くすべての引数が必要な場合:

args=( "$@" )
unset args[0] args[3] args[4]
echo "${args[@]}"

コピーでは、$0はの一部ではないため、インデックスは1シフトされ$@ます。


1
もちろんecho "${args[@]:2}"、3番目から最後の引数など、それを組み合わせることができます。
デザート
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.