$ * Ve bash betiğinde $ 1 ve $ 2 gibi bazı giriş değişkenlerini atlarken nasıl kullanırım?


15

Örneğin,

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

aşağıdaki tüm girişleri içeren bir metin dosyası oluşturmak "$2"veya aşağıdaki tüm girişleri içeren mevcut bir metin dosyası eklemek için satır 4'ün "$2"yerine ne kullanırım "$variable_in_question"?

Temel olarak istiyorum "$*", ama ihmal "$1"ve "$2".

Yanıtlar:


32

Bir aralık belirtmek için bashParametre Genişletme'yi kullanabilirsiniz , bu konumsal parametrelerle de çalışır. Çünkü $3$nolurdu:

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

Her ikisinin de farkında olun $@ve $*ilk argümanı görmezden gelin $0. Eğer durumunda kullanılacak hangisini merak edin: bu kadar çok bir alıntı istediğiniz muhtemel $@. Kullanmayın $*açıkça sürece yok argümanlar tek tek alıntı istiyorum.

Aşağıdaki gibi deneyebilirsiniz:

$ 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

İlk örnekte $0, 0bir komut dosyasında kullanıldığında $0, ikinci örnekte gösterildiği gibi komut dosyasının adıyla doldurulurken ilk argümanla doldurulduğunu unutmayın. İçin komut dosyasının adını bashkursu ait olduğunu normalde gibi algılanan değil sadece, ilk argüman - Bir senaryo yürütülebilir yaptı ve “doğrudan” olarak adlandırılan aynı gider. Yani ilk örnekte $0= 0, $1= 1vb. Var, ikincisinde ise $0= script_file, $1= 0, $2= 1vb .; ${@:3}ile başlayan her argümanı seçer $3.

Olası aralıklar için bazı ek örnekler:

 # 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

Daha fazla okuma:


27

shiftYerleşik kullanabilirsiniz :

$ 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 $#.

Ör. verilmiş

$ cat argtest.bash 
#!/bin/bash

shift 2

echo "$*"

sonra

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

3
@Oreoplazm Bence shiftyaklaşımın erişmeyi imkansız hale getireceğini $1ve $2siz değiştirdikten sonra bahsetmeye değer . Komut dosyanızda $2birlikte kullandığınız komut dosyasında $variable_in_question, bunu değiştirmeniz veya Parametre Genişletme yaklaşımını kullanmanız gerekir.
tatlı

6
shiftİyi bir ilk bir veya birden fazla bağımsız değişken özeldir ve (ayrı değişkenlere onları almaya mantıklı zaman olduğu foo="$1"; bar="$2";ya if [[ something with $1 ]];then blah blah; shift. Ama ne zaman tahribatsız yaklaşımla tatlı'nın cevap @ diğer durumlarda güzel yapmak hala daha sonra tam listesini istiyorum veya $@çok fazla öğeye sahip değilse bir komuta boş argümanlar getirmeden, sonsuzluğa değil, sınırlı sayıda argümanı seçmek için meraklı sözdizimini kullandığınızda
Peter Cordes

13

Genel olarak, konum parametrelerini bir diziye kopyalayabilir, dizinin rasgele dizinlerini silebilir ve sonra diziyi, orijinal argümanlarınızı kaybetmeden tam olarak istediğiniz dizinlere genişletmek için kullanabilirsiniz.

Örneğin, birinci, dördüncü ve beşinci hariç tüm argümanları istersem:

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

Kopyada, endeksler bir $0parçası olmadığı için 1 ile kaydırılır $@.


1
Elbette bunu birleştirmek mümkündür, örneğin echo "${args[@]:2}"üçüncü ila son argüman için.
tatlı
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.