1

I am writing a script to create/copy files to speed up workflow. In this instance a directory needs to be searched for files ending in a specific string, and if one or more is found the last one in the sequence needs to be targeted to be copied. (If none are found, the script copies a fresh file in from a different directory).

This directory can contain multiple sets of files that all follow the format;

YYYYMMDD_##_user_filename.json

So an example folder might contain the following;

20161021_01_test_parameters.json
20161021_01_test_stack.json
20161021_02_test_parameters.json
20161021_02_test_stack.json
20161022_03_test_parameters.json
20161025_04_test_parameters.json
20161025_04_test_stack.json

In this instance I need the script to read for any file ending in parameters.json and then sort them based on their version number (01, 02, etc) to discover which is the last one in the sequence. This file should then be copied into the same folder using the next version number. For this purpose the date is irrelevant and you can assume there will never be duplicate version numbers.

I was using if [ -e $1/*"parameters.json" ]; then cp $1/*"parameters.json" "$FILENAME"_parameters.json (where $1 is the directory these files are being moved about in - important because the script is located outside of the directories to be acted upon, and $FILENAME is just a variable to calculate the location, date, version number, etc) but of course this doesn't do anything about finding the most recent one.

  • @steeldriver Yes and no. That one cut the filename down into just the version number which could be used as a variable. Here I need to preserve which file that version number is attached to so I know which one to copy. I assume the beginning of the sequence is a similar find option, but how to sort by the variable number without isolating it from the filename? – Alex Oct 26 '16 at 17:50
  • @steeldriver Oh gosh nevermind I figured it out using a bit of what you taught me yesterday. Is there a way to close an unanswered question? (And sorry for bothering you!) – Alex Oct 26 '16 at 17:57
2

Since the number on which you want to sort appears to always be the second underscore-delimited field, you should be able to use something like

find path/to/dir/ -maxdepth 1 -name '*parameters.json' | sort -t_ -nk2,2 | tail -n1

If you need to handle the possibility of filenames that contain newlines, and your core utilities support it, you can turn the whole command null delimited e.g.

find path/to/dir/ -maxdepth 1 -name '*parameters.json' -print0 | sort -zt_ -nk2,2 | tail -zn1
  • This is way shorter than what I had come up with! Fantastic answer, thank you. Just so I know I understand what I'm using, what does the -nk2,2 section mean specifically? I get that it's somehow indicating which field to use, but not how. – Alex Oct 26 '16 at 18:10
  • @Alex nk2,2 means numeric sort, on the fields from #2 to #2 i.e. considering field #2 only - see man sort for a fuller description – steeldriver Oct 26 '16 at 18:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.