web-dev-qa-db-fra.com

Comment boucler une commande exécutable dans le terminal sous Linux?

Permettez-moi d'abord de décrire ma situation, je travaille sur une plate-forme Linux et j'ai une collection de .bmp fichiers qui en ajoutent un au numéro de l'image de filename0022.bmp Jusqu'à filename0680.bmp. Soit un total de 658 photos. Je veux pouvoir exécuter chacune de ces images via un fichier .exe qui opère sur l'image puis envoie le fichier dans un fichier spécifié par l'utilisateur, il a également des arguments de seuil: inférieur, supérieur. Ainsi, l'appel typique pour l'exécutable est:

./filter inputfile outputfile lower upper

Existe-t-il un moyen de boucler cet appel sur tous les fichiers uniquement à partir du terminal ou en créant une sorte de script bash? Mon problème est similaire à ceci: Exécuter une commande sur plusieurs fichiers avec un fichier batch mais cette fois je travaille dans un terminal de ligne de commande Linux.

14
Linux Rules

Vous pouvez essayer quelque chose comme ça ...

#! /bin/bash
for ((a=022; a <= 658 ; a++))
do
   printf "./filter filename%04d.bmp outputfile lower upper" $a | "sh"
done
8
scottyaz

Vous pourriez être intéressé par des scripts bash.

Vous pouvez exécuter des commandes dans une boucle for directement à partir du shell.

Une simple boucle pour générer les chiffres que vous avez spécifiquement mentionnés. Par exemple, à partir du Shell:

user@machine $ for i in {22..680} ; do
> echo "filename${i}.bmp"
> done

Cela vous donnera une liste de filename22.bmp À filename680.bmp. Cela gère simplement l'itération de la plage que vous avez mentionnée. Cela ne couvre pas les numéros de remplissage zéro. Pour ce faire, vous pouvez utiliser printf. La syntaxe printf est printf format argument. Nous pouvons utiliser la variable $i De notre boucle précédente comme argument et appliquer le format %Wd Où W est la largeur. Le préfixe de l'espace réservé W spécifie le caractère à utiliser. Exemple:

user@machine $ for i in {22..680} ; do
> echo "filename$(printf '%04d' $i).bmp"
> done

Dans la fonction ci-dessus, $() agit comme une variable, exécutant des commandes pour obtenir la valeur opposée à une valeur prédéfinie.

Cela devrait maintenant vous donner les noms de fichiers que vous avez spécifiés. Nous pouvons prendre cela et l'appliquer à l'application réelle:

user@machine $ for i in {22..680} ; do
> ./filter "filename$(printf '%04d' $i).bmp" lower upper
> done

Cela peut être réécrit pour former une seule ligne:

user@machine $ for i in {22..680} ; do ./filter "filename$(printf '%04d' $i).bmp" lower upper ; done

Une chose à noter de la question, les fichiers .exe sont généralement compilés au format COFF où linux attend un exécutable au format ELF.

15
Steve Buzonas

voici un exemple simple:

for i in {1..100}; do echo "Hello Linux Terminal"; done

pour ajouter à un fichier: (>> est utilisé pour ajouter, vous pouvez également utiliser> pour écraser)

for i in {1..100}; do echo "Hello Linux Terminal" >> file.txt; done
10
vishal

Vous pouvez tester que AS-IS dans votre Shell:

for i in *; do
    echo "$i" | tr '[:lower:]' '[:upper:]'
done

Si vous avez un chemin spécial, changez * par votre chemin + un glob: Ex:

for i in /home/me/*.exe; do ...

Voir http://mywiki.wooledge.org/glob

1
Gilles Quenot

Vous pouvez utiliser xargs pour itérer:

ls | xargs -i ./filter {} {}_out lower upper

Remarque:

  • {} correspond à une sortie de ligne du tube, ici c'est le nom du fichier d'entrée.
  • Les fichiers de sortie seraient nommés avec le suffixe "_out".
1
howardoer

Ceci tout en ajoutant le nom des images de sortie comme filtered_filename0055.bmp

for i in *; do
    ./filter $i filtered_$i lower upper
done
0
Eric Fortis