web-dev-qa-db-fra.com

Comment utiliser les lignes d'un fichier comme arguments d'une commande?

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?

125
Yoo

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

194
glenn jackman

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
35
Will

Vous faites cela en utilisant des backticks:

echo World > file.txt
echo Hello `cat file.txt`
15
Tommy Lacroix
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
14
Wesley Rice

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 "$@"
7
Charles Duffy

Voici comment je passe le contenu d'un fichier en tant qu'argument d'une commande:

./foo --bar "$(cat ./bar.txt)"
6
chovy

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 .

2
honkaboy