I have 4 files :
text1005.txt
text1007.txt
text1009.txt
text1012.txt
I create list :
FILES=$(find -type f -name "*txt")
arr=${FILES}
But when I want to print the indices, it doesn't give the good file. For example,
echo ${arr[1]}
./text1009.txt
It should've given to me the first file in the list which is text1005.txt
. It will be problematic because later, I will use the $SLURM_ARRAY_TASK_ID
variable , so I need the indices match with the good file.
Any suggestion?
First, avoid all-caps vars.
Second,
files=$(find -type f -name "*txt")
creates a single variable, not an array -
$: echo "$files"
./text1005.txt
./text1007.txt
./text1009.txt
./text1012.txt
$: echo "${#files[@]}"
1
To make in at array, you need parens.
files=( $(find -type f -name "*txt") )
Third, find
does not implicitly sort its output.
If you need explicitly sorted output, explicitly sort your output. :)
files=( $(find -type f -name "*txt" | sort ) ) # sort has lots of options
This seems like a bit of overkill if just for the files to be lexically sorted, which is the default output for simple globbing. In your find
you explicitly limit files to -type f
, which is good, but since all the files in your example are *.txt
(which I take to imply text files) it may be unnecessary. Let the interpreter handle it without starting three (yes, three) subprocesses.
$: files=( *txt ) # faster & easier to read
$: echo "${files[@]}"
text1005.txt text1007.txt text1009.txt text1012.txt
$: echo "${#files[@]}"
4
$: echo "${files[0]}"
text1005.txt
$: echo "${files[2]}"
text1009.txt
Does that do what you want?