Dis, j'ai un fichier foo.txt
spécifiant N
arguments
arg1
arg2
...
argN
que je dois passer à la commande my_command
Comment utiliser les lignes d'un fichier comme arguments d'une commande?
Si votre shell est bash (entre autres), un raccourci pour $(cat afile)
est $(< afile)
, vous pouvez donc écrire:
mycommand "$(< file.txt)"
Documenté dans la page de manuel bash de la section 'Substitution de commande'.
Modifiez votre commande à partir de stdin. Ainsi: mycommand < file.txt
Comme déjà mentionné, vous pouvez utiliser les backticks ou $(cat filename)
.
Ce qui n’a pas été mentionné, et je pense qu’il est important de noter, c’est que vous devez vous rappeler que le shell divisera le contenu de ce fichier en fonction des espaces, en donnant chaque "mot" trouvé à votre commande en tant qu’argument. Et même si vous pouvez inclure un argument de ligne de commande entre guillemets pour qu'il puisse contenir des espaces, des séquences d'échappement, etc., la lecture du fichier ne fera pas la même chose. Par exemple, si votre fichier contient:
a "b c" d
les arguments que vous obtiendrez sont:
a
"b
c"
d
Si vous voulez tirer chaque ligne en argument, utilisez la construction while/read/do:
while read i ; do command_name $i ; done < filename
Vous faites cela en utilisant des backticks:
echo World > file.txt
echo Hello `cat file.txt`
command `< file`
passera le contenu du fichier à la commande sur stdin, mais supprimera les nouvelles lignes, ce qui signifie que vous ne pourrez pas parcourir chaque ligne individuellement. Pour cela, vous pouvez écrire un script avec une boucle 'pour':
for i in `cat input_file`; do some_command $i; done
Si vous souhaitez effectuer cette opération de manière robuste et compatible avec tous les arguments possibles de la ligne de commande (valeurs avec espaces, nouvelles lignes, valeurs avec des guillemets, valeurs non imprimables, valeurs avec des caractères globaux, etc.), vous obtenez un bit. plus intéressant.
Pour écrire dans un fichier, à l'aide d'un tableau d'arguments:
printf '%s\0' "${arguments[@]}" >file
...remplacer par "argument one"
, "argument two"
, etc. selon le cas.
Pour lire à partir de ce fichier et utiliser son contenu (dans bash, ksh93 ou un autre shell récent avec tableaux):
declare -a args=()
while IFS='' read -r -d '' item; do
args+=( "$item" )
done <file
run_your_command "${args[@]}"
Pour lire à partir de ce fichier et utiliser son contenu (dans un Shell sans tableaux), notez que cela écrasera votre liste d'arguments de ligne de commande locale et qu'il est donc préférable de le faire à l'intérieur d'une fonction, de sorte que vous écrasez les arguments de la fonction et non la liste globale):
set --
while IFS='' read -r -d '' item; do
set -- "$@" "$item"
done <file
run_your_command "$@"
Notez que -d
(autorisant l’utilisation d’un délimiteur de fin de ligne différent) est une extension non-POSIX, et un shell sans tableaux risque de ne pas la prendre en charge. Si cela devait être le cas, vous devrez peut-être utiliser un langage non-shell pour transformer le contenu délimité par NUL en une forme eval
-safe:
quoted_list() {
## Works with either Python 2.x or 3.x
python -c '
import sys, pipes, shlex
quote = pipes.quote if hasattr(pipes, "quote") else shlex.quote
print(" ".join([quote(s) for s in sys.stdin.read().split("\0")][:-1]))
'
}
eval "set -- $(quoted_list <file)"
run_your_command "$@"
Voici comment je passe le contenu d'un fichier en tant qu'argument d'une commande:
./foo --bar "$(cat ./bar.txt)"
Dans mon shell bash, les éléments suivants ont fonctionné à merveille:
cat input_file | xargs -I % sh -c 'command1 %; command2 %; command3 %;'
où input_file est
arg1
arg2
arg3
Comme il est évident, cela vous permet d’exécuter plusieurs commandes avec chaque ligne de input_file, un joli petit truc que j’ai appris ici .