Reputation: 467
I have an issue. I have a folder with many files and i need to execute a program on all combinations of 2 files among my files.
My linux bash script looks like this so far:
for ex in $(ls ${ex_folder}/${testset_folder} | sort -V ); do
#ex is the name of my current file
#I would like to do something like a nested loop where
# ex2 goes from ex to the end of the list $(ls ${ex_folder}/${testset_folder} | sort -V )
done
I'm new to bash, in other languages this would look something like:
for i in [0,N]
for j in [i,N]
#the combination would be i,j
My list of files looks like the following:
ex_10.1 ex_10.2 ex_10.3 ex_10.4 ex_10.5
And i want to execute a python program on all combinations of 2 files among these (so i execute my program 10 times)
Thank you in advance for your help!
Upvotes: 2
Views: 2737
Reputation: 295443
The logic you describe is easily transcribed if we use an array, and iterate by index:
files=( * ) # Assign your list of files to an array
max=${#files[@]} # Take the length of that array
for ((idxA=0; idxA<max; idxA++)); do # iterate idxA from 0 to length
for ((idxB=idxA; idxB<max; idxB++)); do # iterate idxB from idxA to length
echo "A: ${files[$idxA]}; B: ${files[$idxB]}" # Do whatever you're here for.
done
done
To safely implement sort -V
(in a manner that doesn't allow malicious filenames or bugs to inject extra entries into the array), we'd want to replace that initial assignment line with logic akin to:
files=( )
while IFS= read -r -d '' file; do
files+=( "$file" )
done < <(printf '%s\0' * | sort -V -z)
...which uses NUL delimiters (which, unlike newlines, cannot exist as a literal in UNIX filenames) to separate names in the stream to and from sort
.
Upvotes: 6