Generally, you wouldn't as the output of ls
is not post-processable reliably.
For instance:
open -- "$(ls -t | head -n 1)"
doesn't work if the name of newest file contains newline characters.
Ideally, you'd want:
ls -zt | head -zn1 | xargs -r0 open --
But unfortunately, I don't know of any ls
implementation that supports a -z
/-0
option, and the maintainers of GNU ls
at least declined several times to add it.
Now, there are other ways with some implementations.
With the GNU and ast-open implementations of ls
, in the C locale, the output with the --quoting-style=shell-always
option is post-processable by zsh
, ksh93
or bash
:
export LC_ALL=C
eval "files=($(ls --quoting-style=shell-always -t))"
open -- "${files[0]}" # $files[1] with zsh
Though in zsh, you'd just do
open ./*(om[1])
or:
open ./Ctrl+Xm
as zsh
has built-in support to sort files by modification time (and many other criteria that go far beyond ls
capabilities).
FreeBSD ls
has a --libxo
option to generate json or xml output, so you could do:
ls --libxo=json -t | perl -MJSON::PP -0777 -l0 -ne '
print decode_json($_)
->{"file-information"}
->{directory}->[0]
->{entry}->[0]
->{name}' | xargs -r0 open --
But then it would be simpler to do the whole thing in perl
.
ls
is number 1 in BashPitfalls. If you can tell what you want to do, we might be able to point to a better solution – ilkkachu Nov 29 '17 at 22:19ls
. You should probably look into either usingfind
or simple shell globbing to get your list of files to process. Extensive further reading on the subject can be found here. – DopeGhoti Nov 29 '17 at 22:32somecmd "$(ls -tr | tail -1)"
-- That will burn in a number of edge cases, most of which involve dashes, control characters or newlines in file names. I already feel like I've done something horrible, just writing that. – ilkkachu Nov 29 '17 at 22:38somecmd "$(ls -tr | tail -1)"
works. I understand that it is hacky and burns in edge cases, but still it is useful for my personal use. Thanks. – villybyun Nov 29 '17 at 23:58