Bash doesn't yet make it easy to sort files by modification time, so here's the obligatory zsh-based answer. You don't have to switch to zsh as your login shell in order to use its features.
Here I set up a wrapper function that expects either one or two arguments; the first argument is the program to execute (e.g. myprogram
); the second, optional, argument is the directory containing the files that you want to pass to the program. If you don't specify a second argument, it defaults to the current directory.
zeio() {
# Zsh-based Execute with files In Order
[ -d "${2:-.}" ] || return
zsh -c "$1 \"${2:-.}\"/*(.om)"
}
Name it whatever you like, of course. After a quick sanity-check of the second argument (again, defaulting to .
, the current directory), we call zsh with a single double-quoted string that contains the program and some initial arguments (argument #1) and the directory (argument #2) — defaulting to .
— with a wildcard / glob expansion that has two "glob qualifiers" in the trailing parenthesis:
.
-- must be regular files (not directories or symlinks, etc)
om
-- o
rder (sort) the resulting list by modification time, most recent first
It's that om
glob qualifier that does all of the real work here.
Here's some sample runs; myprog
is a simple shell script to demonstrate the arguments it receives, in order:
#!/bin/sh
for arg do
printf 'Arg: ->%s<-\n' "$arg"
done
and go.sh
is the file where I saved the function. The rest of the directory structure is:
$ tree .
.
├── dir1
│ ├── 203142
│ ├── 203143
│ └── 203144
├── dir3
│ ├── first\012filename
│ ├── this is 3rd
│ └── this is second
├── dir two
│ ├── 203225
│ ├── 203226
│ └── 203227
├── go.sh
└── myprog
... where I've created the sets of three files in each subdirectory in the listed sequence; I expect to see them in this same order when I execute the function. The first filename under dir3 has a newline in it, represented by tree
with \012
. The results are:
Demonstrating the default-to-current-directory behavior:
$ zeio ./myprog
Arg: ->./myprog<-
Arg: ->./go.sh<-
Normal filename demonstration
$ zeio ./myprog dir1
Arg: ->dir1/203142<-
Arg: ->dir1/203143<-
Arg: ->dir1/203144<-
Directory has a space in it
$ zeio ./myprog "dir two"
Arg: ->dir two/203225<-
Arg: ->dir two/203226<-
Arg: ->dir two/203227<-
filenames have whitespace in them
$ zeio ./myprog dir3
Arg: ->dir3/first
filename<-
Arg: ->dir3/this is second<-
Arg: ->dir3/this is 3rd<-
parsing ls
not good practice?ls -rt | myprogram
would work, the filename if it has a space would simply beobject-oriented\ data\ model.pdf
using a backslash before each space. Or ifmyprogram
is written in C you could usepopen("ls -rt", "r")
I do this all the time and it works great. – ron Apr 22 '19 at 14:20ls ... | myprogram
would provide the filenames (as output fromls
) as stdin to the program, not as arguments, as requested. Also note that any filename with a newline in it will be sent as two separate lines to the program, which would no longer be able to distinguish them from two separate filenames. – Jeff Schaller Apr 22 '19 at 18:25myprogram
? A bash script, csh/tcsh script, ksh? or is it an executable compiled from C code? or python, java... ? – ron Apr 22 '19 at 21:21