J'ai un certain nombre de fichiers et je veux utiliser leurs noms comme arguments pour une commande afin que la commande devienne
lcov -o total.coverage -a <file1> -a <file2> ...
Pour chaque nom de fichier, je veux ajouter le nom de l'option. Je ne sais pas combien de fichiers il y a. Comment puis-je faire ceci? Est-ce que bash / shell a quelque chose de similaire à map
?
Les fichiers existent donc j'obtiendrais les noms en utilisant find
, ou mayb ls si je suis sûr des noms de fichiers, je cherchais donc quelque chose comme vous pouvez le faire avec
xargs
ls -1q <pattern> | xargs <command> ...
Mais au lieu de quoi xargs
do (en le transformant en une commande pour chaque fichier) Je veux une seule commande avec de nombreux arguments avec insérée avant tous les noms de fichiers.
Dans mon exemple spécifique, je veux combiner un nombre inconnu de fichiers de données de couverture avec une seule commande:
<command> <option> <file1> <option> <file2> ...
Ceci est à l'intérieur d'un Makefile, mais je préférerais un shell "standard" approche.
5 Réponses :
Vous pouvez faire:
ls <pattern> |sed "s/^/-optionItself /g"|xargs
ajoutant ainsi -optionItself
devant chaque nom de fichier, puis l'envoyer à xargs
p>
Je suis sûr qu'il existe de nombreuses autres façons d'accomplir cela, c'est la plus simple et la plus proche de ce avec quoi vous travaillez.
C'est aussi sympa. Et c'est un shell standard, qui fonctionne dans un Makefile.
Peut-être ceci?
function multi_lcov(){ files_params=($@) lcov ${files_params[@]} } multi_lcov "$(ls | sed -r 's/(.*)/\-a \1/g')"
Essayez ceci:
files=(pattern) # This will expand the [pattern], and put all the files in [files] variables lcov -o total.coverage ${files[@]/#/-a } # ${files[@]/#/-a } replaces the beginning of each element in files with [-a ], # meaning prepend [-a ] # For more information, see section [${parameter/pattern/string}] in # https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#Shell-Parameter-Expansion
en supposant que vous n'avez pas de caractères spéciaux (comme des espaces) dans vos noms de fichiers.
Parfait! Si vous expliquez un peu plus, j'accepterai votre réponse.
Oops. Bien sûr, cela ne fonctionnait pas dans un Makefile ( bash
au lieu de sh
qui est le shell standard utilisé par make
). Mais puisque je voulais une solution générale c'est toujours un candidat ;-)
Je pense que vous pouvez redéfinir SHELL dans votre Makefile.
Oui, mais je ne veux pas faire ça.
Lorsque vous recherchez les fichiers, imprimez également l'option, utilisez des flux séparés par zéro pour gérer tous les noms de fichiers possibles:
find . -maxdepth 1 -mindepth 1 -type f -printf "-a\n%p\n" | xargs -d '\n' lcov -o total.coverage
De même avec une nouvelle ligne comme séparateur pour les éléments de la liste:
XXX
fileslist=( $(cd /path/to/files/you/want/ ;find -maxdepth 1 -printf "%P\n" | xargs -0) ) for t in ${fileslist[@]} do commandtoperform $t done
-printf "% P \ n" | xargs -0
n'a aucun sens. Juste printf "% P \ n"
.
D'où viennent les listes?
J'ai une liste de noms de fichiers
comment les noms de fichiers sont-ils stockés? À l'intérieur d'un tableau bash? Dans un dossier? Dans une variable? Dans une variable make? Dans la variable bash? Les entrées de la variable sont-elles séparées par des retours à la ligne? Sont-ils terminés par zéro? Par un autre personnage? Veuillez poster un code.Est-ce que bash / shell a quelque chose de similaire à map?
oui, bash a des ararys associatifs.Ils ne viennent de nulle part. Modifié pour être plus clair à ce sujet.
Les fichiers existent donc j'obtiendrais les noms en utilisant ls
ne pas analyser la sortie ls@KamilCuk était d'accord en général, mais dans ce cas, je contrôle totalement les fichiers et leurs noms. Mais je vais mettre à jour pour le bénéfice du cas plus général.
Ensuite, utilisez au moins
ls -1
. (ls -1q
)