Your method can be adapted to work in simple cases. The main problem you're facing is that you're passing input to
ls doesn't take any input.
ls takes command line arguments. So you need to pass the output of
find as arguments to
ls, with a command substitution. Also, in case a directory is matched, pass
ls to list the directory itself and not its contents.
OLDDATA=$(ls -td $(find . -regex ".*/[0-9.]+"))
Only in simple cases, because there are two restrictions:
- This relies on an unquoted command substitution (and so does the use of
$OLDDATA afterwards). Therefore it assumes that the file names don't contain any special characters (whitespace or wildcard characters
- Some versions of
ls may mangle characters that are not printable in the current locale.
- If the total length of the file names is too long, you'll get an error. (Note that
find … -exec and
xargs cannot help here, since
ls must run a single time to get the order of the file names right. All they could do is hide errors and produce output that is not correctly sorted — and mangle a few more characters, in the case of
A robust, simple way of doing this is to use zsh. It has the ability to sort wildcard matches, thanks to glob qualifiers.
- Since this doesn't call any other program, there is no length limit other than available memory, and no risk of file name mangling at any point.
- The result is a list of strings (each string being a file name), not a string, so it goes into an array variable.
**/ traverses subdirectories recursively, avoiding the use of
## means “one or more of the preceding” in zsh extended glob syntax, it's analogous to
+ in (extended) regex syntax.
(om) is a glob qualifier to sort files by modification time, like
There is notoriously no simple way to do this robustly with POSIX tools or even with GNU tools and ksh.