Search code examples
arraysbashslurmindices

Indices of batch array not in the good order


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?


Solution

  • 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?