I need to write a script that starts my program with different arguments, but I'm new to Bash. I start my program with:
./MyProgram.exe Data/data1.txt [Logs/data1_Log.txt]
.
Here is the pseudocode for what I want to do:
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
So I'm really puzzled how to create second argument from the first one, so it looks like dataABCD_Log1.txt and start my program.
for file in Data/*.txt
do
for ((i = 0; i < 3; i++))
do
name=${file##*/}
base=${name%.txt}
./MyProgram.exe "$file" Logs/"${base}_Log$i.txt"
done
done
The name=${file##*/}
substitution (shell parameter expansion) removes the leading pathname up to the last /
.
The base=${name%.txt}
substitution removes the trailing .txt
. It's a bit trickier if the extensions can vary.
You can use finds null separated output option with read to iterate over directory structures safely.
#!/bin/bash
find . -type f -print0 | while IFS= read -r -d $'\0' file;
do echo "$file" ;
done
So for your case
#!/bin/bash
find . -maxdepth 1 -type f -print0 | while IFS= read -r -d $'\0' file; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$file" 'Logs/'"`basename "$file"`""$i"'.txt'
done
done
additionally
#!/bin/bash
while IFS= read -r -d $'\0' file; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$file" 'Logs/'"`basename "$file"`""$i"'.txt'
done
done < <(find . -maxdepth 1 -type f -print0)
will run the while loop in the current scope of the script ( process ) and allow the output of find to be used in setting variables if needed
Looks like you're trying to execute a windows file (.exe) Surely you ought to be using powershell. Anyway on a Linux bash shell a simple one-liner will suffice.
[/home/$] for filename in /Data/*.txt; do for i in {0..3}; do ./MyProgam.exe Data/filenameLogs/$filename_log$i.txt; done done
Or in a bash
#!/bin/bash
for filename in /Data/*.txt;
do
for i in {0..3};
do ./MyProgam.exe Data/filename.txt Logs/$filename_log$i.txt;
done
done
Sorry for necromancing the thread, but whenever you iterate over files by globbing, it's good practice to avoid the corner case where the glob does not match (which makes the loop variable expand to the (un-matching) glob pattern string itself).
For example:
for filename in Data/*.txt; do
[ -e "$filename" ] || continue
# ... rest of the loop body
done
Reference: Bash Pitfalls
Source: Stackoverflow.com