J'ai besoin d'écrire un script qui démarre mon programme avec différents arguments, mais je suis nouveau sur Bash. Je commence mon programme avec:
./MyProgram.exe Data/data1.txt [Logs/data1_Log.txt]
.
Voici le pseudocode de ce que je veux faire:
for each filename in /Data do
for int i = 0, i = 3, i++
./MyProgram.exe Data/filename.txt Logs/filename_Log{i}.txt
end for
end for
Je suis donc vraiment perplexe sur la façon de créer un deuxième argument à partir du premier, il ressemble donc à dataABCD_Log1.txt et démarre mon programme.
basename -s
c'est une extension non standard - je vais modifier ma réponse pour utiliser la syntaxe standard.shopt -s nullglob
avant la boucle (etshopt -u nullglob
après pour éviter les problèmes plus tard), soit ajouterif [[ ! -e "$filename ]]; then continue; fi
au début de la boucle, donc il sautera les fichiers inexistants.Désolé pour le nécromancement du thread, mais chaque fois que vous parcourez des fichiers en globulant, il est recommandé d'éviter le cas d'angle où le glob ne correspond pas (ce qui fait que la variable de boucle se développe jusqu'à la chaîne de motif de glob (non-correspondante) elle-même).
Par exemple:
Référence: Bash Pitfalls
la source
shopt nullglob
! (oushopt failglob
peut également être utilisé, selon le comportement que vous souhaitez).dir.txt
La
name=${file##*/}
substitution ( expansion des paramètres du shell ) supprime le chemin d'accès principal jusqu'au dernier/
.La
base=${name%.txt}
substitution supprime le suivi.txt
. C'est un peu plus compliqué si les extensions peuvent varier.la source
base=${name%.txt}
, au lieu debase=${base%.txt}
.Vous pouvez utiliser l'option de sortie séparée par des résultats avec lecture pour parcourir les structures de répertoires en toute sécurité.
Donc pour votre cas
aditionellement
exécutera la boucle while dans la portée actuelle du script (processus) et autorisera la sortie de find à définir des variables si nécessaire
la source
$'\0'
est une façon étrange d'écrire''
. Vous êtes absentIFS=
et le-r
passage àread
: votre relevé de lecture doit être:IFS= read -rd '' file
.$'\0'
et de répartir des points de pile autour. Je vais apporter les modifications que vous avez signalées. Quels sont les effets néfastes de ne pas y avoirIFS=
essayéecho -e "ok \nok\0" | while read -d '' line; do echo -e "$line"; done
ne semblent pas en avoir. Aussi -r je vois est souvent par défaut, mais n'a pas pu trouver d'exemple pour ce qu'il empêche de se produire.IFS=
est nécessaire dans le cas où un nom de fichier se termine par un espace: essayez est avectouch 'Prospero '
(notez l'espace de fin). Vous avez également besoin du-r
commutateur dans le cas où un nom de fichier a une barre oblique inverse: essayez-le avectouch 'Prospero\n'
.On dirait que vous essayez d'exécuter un fichier Windows (.exe) Vous devriez sûrement utiliser PowerShell. Quoi qu'il en soit, sur un shell bash Linux, une simple ligne suffit.
Ou dans un bash
la source