web-dev-qa-db-fra.com

Comment utiliser $ * en omettant certaines variables d'entrée telles que $ 1 et $ 2 dans le script bash?

Par exemple,

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

soit créer un fichier texte contenant toutes les entrées suivant "$2", soit ajouter un fichier texte existant contenant toutes les entrées suivant "$2", que pourrais-je utiliser à la place de "$variable_in_question" à la ligne 4?

Je veux fondamentalement "$*", mais en omettant "$1" et "$2".

14
Oreoplasm

Vous pouvez utiliser bashExpansion des paramètres pour spécifier une plage. Cela fonctionne également avec les paramètres de position. Pour $3$n ce serait:

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

Sachez que $@ et $* ignorent le premier argument $0. Si vous vous demandez lequel utiliser dans votre cas: c’est très probablement vous voulez un $@ entre guillemets. Ne pas utiliser $* à moins que vous ne vouliez explicitement que les arguments ne soient pas cités individuellement.

Vous pouvez l'essayer comme suit:

$ 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

Notez que, dans le premier exemple, $0 est rempli avec le premier argument 0, mais qu’il est utilisé dans un script, $0 est également rempli avec le nom du script, comme le montre le deuxième exemple. Le nom du script à bashbien sûr est le premier argument, mais il n'est normalement pas perçu comme tel - il en va de même pour un script rendu exécutable et appelé “ directement". Ainsi, dans le premier exemple, nous avons $0 = 0, $1 = 1 etc., tandis que dans le second, il s'agit de $0 = script_file, $1 = 0, $2 = 1 etc .; ${@:3} sélectionne tous les arguments commençant par $3.

Quelques exemples supplémentaires pour les plages possibles:

 # 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

Lectures complémentaires:

31
dessert

Vous pouvez utiliser le nom intégré 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 $#.

Ex. donné

$ cat argtest.bash 
#!/bin/bash

shift 2

echo "$*"

puis

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

En règle générale, vous pouvez copier les paramètres de position dans un tableau, supprimer des index arbitraires du tableau, puis utiliser le tableau pour développer exactement les index souhaités, sans perdre vos arguments d'origine.

Par exemple, si je voulais tous les arguments sauf les premier, quatrième et cinquième:

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

Dans la copie, les index sont décalés de 1, car $0 ne fait pas partie de $@.

13
muru