A couple of notes first: when you use Data/data1.txt as an argument, should it really be /Data/data1.txt (with a leading slash)? Also, should the outer loop scan only for .txt files, or all files in /Data? Here’s an answer, assuming /Data/data1.txt and .txt files only:
#!/bin/bash
for filename in /Data/*.txt; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$filename" "Logs/$(basename "$filename" .txt)_Log$i.txt"
done
done
Notes:
/Data/*.txt expands to the paths of the text files in /Data (including the /Data/ part)
$( ... ) runs a shell command and inserts its output at that point in the command line
basename somepath .txt outputs the base part of somepath, with .txt removed from the end (e.g. /Data/file.txt -> file)
If you needed to run MyProgram with Data/file.txt instead of /Data/file.txt, use “${filename#/}” to remove the leading slash. On the other hand, if it’s really Data not /Data you want to scan, just use for filename in Data/*.txt.
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