2

How to get a list of the latest files with the extension .jmx recursively and use the file names in another process?

I have a list of JMX files organized into different folders and want to pick the latest file in each subfolder and use the JMX files in another process. (run the JMeter tests)

Ideally, the latest file should be the one with the higher version number available in the file name.

Sample list from two subfolders

/test_plans/accounts/filter/TestPlan-API-Accounts-Filter-1.2.jmx
/test_plans/accounts/filter/TestPlan-API-Accounts-Filter-1.1.jmx
/test_plans/accounts/filter/TestPlan-API-Accounts-Filter-1.0.jmx

/test_plans/account-activation/TestPlan-Account-Activation-1.2.jmx
/test_plans/account-activation/TestPlan-Account-Activation-1.1.jmx
/test_plans/account-activation/TestPlan-Account-Activation-1.1 .jmx
/test_plans/account-activation/TestPlan-Account-Activation-1.0 .jmx

I need to pick TestPlan-API-Accounts-Filter-1.2.jmx and TestPlan-Account-Activation-1.2.jmx

I can get a list of files recursively with find ./test_plans -type f | sort -nr

3
  • 1
    How would you handle the two filenames TestPlan-Account-Activation-1.1.jmx (without a space) and TestPlan-Account-Activation-1.1 .jmx (with a space). Are they the same or are they different (and if so, which one is later)?
    – Kusalananda
    Aug 14, 2021 at 5:38
  • 1
    Do you have versions like 1.10 or 1.09? Or like 2.2.1 or 1.1p3?
    – Kusalananda
    Aug 14, 2021 at 5:44
  • 1
    I should not have spaces in the file names. This is a typo. I will have versions like 1.10, 1.09 and 2.2.1 but not like 1.1p3. Aug 14, 2021 at 6:53

1 Answer 1

3

With zsh, you could do:

typeset -A latest
for jmx (**/*.jmx(nN)) latest[$jmx:h]=$jmx

Which builds the $latest associative array, where latest[some/dir]=some/dir/file-99.jwx with the value being the file whose name sorts last numerically (thanks to the n glob qualifier which enables numericglobsort for that glob).

Then to do something with those files:

ls -ld -- $latest

Or loop over them with:

for file ($latest) {
  ...
}

Or the Bourne-style syntax if you prefer:

for file in $latest; do
  ...
done

To loop over the keys (the directories) of the associative array:

for dir (${(k)latest}) ...

Or both key and value:

for dir file (${(kv)latest}) ...

(though you can always also use dir=$file:h to get the parent directory from the file, or $latest[$dir] for the dir from the file).

To sort the files by last modification time instead of numerically on their name, replace the n glob qualifier with Om.

To do something similar with GNU bash 4.4+, find and GNU sort:

typeset -A latest
readarray -td '' files < <(
  LC_ALL=C find . -name '.?*' -prune -o -name '*.jmx' -print0 |
    sort -zV)
for jmx in "${files[@]}"; do
  latest[${jmx%/*}]=$jmx
done

And then:

ls -ld -- "${latest[@]}"
for file in "${latest[@]}"; do
  ...
done
for dir in "${!latest[@]}"; do
  file=${latest[$dir]}
  ...
done

Above, it's sort -V (version sort) that sorts the list of files in a similar fashion as zsh's n glob qualifier.

sort -n wouldn't work as it's only for sorting numbers alone.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .