I have a set of folders that are regularly updated, which I would like to regularly parse through and update to a simple text file list. This list gets used with rsync so I shorten the file names using sed for easy syncing.

They are set up pretty much like this:

  • software_folder
    • software_version_1
      • version_1.1
        • some_files
      • version_BETA
        • some_files
    • software_version_2
      • version_2.2
        • some_files
      • version_BETA
        • some_files

I've tried something like:

for dir in `find -maxdepth 2 -type d -name '*BETA'`; do test `find $dir -type f -mtime -1` | echo $dir | sed "s|^\./||" >> list.txt; done

But the output is still listing all BETA folders (and gives an 'unknown operand' error on .aspx files?).

It would be a bonus if the script could move on to the next folder after it finds a minimum of one modified file and updates the folder list, just so it doesn't have to iterate through the rest of the files per folder.

  • There is a package called tree on many distributions which may help you.
    – SauceCode
    Jun 17, 2016 at 0:58
  • If you run that (just type tree inside your directory) you get the contents of your directories listed like you have set out. I'm not sure how you wish to combine that with rsync. It's fast enough that it seems unlikely optimizing with a script to detect changes early would be worth it.
    – SauceCode
    Jun 17, 2016 at 1:06
  • Thank you, however the synology NAS I am working with doesn't support tree. Jun 17, 2016 at 1:27

1 Answer 1


To find all *BETA directories that have new files in them (-mtime -1) and save those directories names in list.txt, try:

find -type f -path '*BETA/*' -mtime -1 | sed 's|^\./||; s|BETA/.*|BETA|' | sort -u >list.txt

Since your goal is to create newline-separated data in the file list.txt, that must mean that you do not expect any of the directories or files to have names which themselves contain newline characters. If they did, then, of course, a different output format would be needed.

How it works

  • find -type f -path '*BETA/*' -mtime -1

    This finds all new files which have a parent directory, somewhere in the path, whose name ends in BETA when new is defined by find's conventions for -mtime -1.

  • sed 's|^\./||; s|BETA/.*|BETA|'

    This removes the initial ./ from the file names and also removes everything after the BETA. The result is the name of the BETA directory.

  • sort -u

    The directory list that sed creates will have duplicates. This removes duplicates.

  • >list.txt

    This saves the output in list.txt

More general solution

The following approach is safe even if directories or files have newline characters in their names (this may require GNU tools):

find -type f -path '*BETA/*' -mtime -1 -print0 | sed -z 's|^\./||; s|BETA/.*|BETA|' | sort -zu >list.out

This creates a file list.out which has the directory names in nul-separated form. Since the nul character can never appear in a file or directory name, this is a safe approach. To use list.out, you would, of course, need to read it with a tool that understands nul-separated input.

  • I gave this a go, unfortunately there doesn't seem to be any output. find -type f -path '*BETA/*' -mtime -1 Testing that and the other versions by itself seems to have no results. Jun 17, 2016 at 1:40
  • Hmm. Maybe there aren't any files new enough. Try find . -type f -path '*BETA/*' and find . -type d -path '*BETA'
    – John1024
    Jun 17, 2016 at 2:04
  • I see from the comments that you are on a Synology NAS. You might check its documentation to see what features its find supports or doesn't support.
    – John1024
    Jun 17, 2016 at 2:10
  • Thank you, I got it with this: find -maxdepth 2 -type d -mtime -1 -name '*BETA*' | sed "s|^\./||" > ~/list.txt Jun 24, 2016 at 0:28

You must log in to answer this question.

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