0

I want to list all files (with absolute path) and only files (not sub-directories) from a given directory in the order of the date modified. I know ls /path_to_dir -t lists files according to the date modified but it does not give the full path More clarification: My work directory is /home/emirates/Code.
From work directory, I want to list :

  • only files with full abs path
  • in the order of the file modified
  • from the directory /var/reports
  • Note that my work directory could change i.e in prod environment it could be anywhere
0

3 Answers 3

3

With zsh:

print -rC1 -- ${PWD%/}/path_to_dir/*(NDom.) # regular files only

print -rC1 -- ${PWD%/}/path_to_dir/*(NDom^/) # any type of file except
                                             # directory (so includes
                                             # symlinks, fifos, devices,
                                             # sockets... in addition to
                                             # the regular files above)

print -rC1 -- ${PWD%/}/path_to_dir/*(NDom-^/) # any type except directory 
                                              # but this time the type is
                                              # determined after symlink
                                              # resolution so would also
                                              # exclude symlinks to
                                              # directories.

print -rC1 -- ${PWD%/}/path_to_dir/*(ND-om^/) # same but also use the
                                              # modification time of the target
                                              # of symlinks when sorting

print -rC1 -- path_to_dir/*(ND-om^/:P) # same but print the real path for each
                                       # file. That is, make sure it's absolute
                                       # and none of the path components
                                       # are symlinks.

${PWD%/} is to handle the case where $PWD is / so we get /path_to_dir/files instead of //path_to_dir/files.

That ${PWD%/}/ is only to be prepended to relative paths (such as path_to_dir) to make them absolute, not for paths that are already absolute (such as /absolute/path_to_dir).

So for your /var/reports, use print -rC1 -- /var/reports/*(...)

0
1

You can use find:

Note that it assumes the GNU implementation of find (and cut and sort which otherwise can't be used portably to process non-text) and that file paths don't contain newline characters. Also note that it excludes directories but also all the other non-regular types of files including symlinks (whether they point to regular files or not), fifos, devices, sockets

find "$PWD/relative_path" -maxdepth 1 -type f -printf "%T@\0%p\n"| sort -rn | cut -d '' -f2

Will list files of the given path, maxdepth tells the level of recursiveness.


Borrowed from Unix/Linux find and sort by date modified.

4
  • 2
    Note that it assumes the GNU implementation of find (and cut and sort which otherwise can't be used portably to process non-text) and that file paths don't contain newline characters. Also note that it excludes directories but also all the other non-regular types of files including symlinks (whether they point to regular files or not), fifos, devices, sockets... Jan 21, 2021 at 16:15
  • 1
    You can't sort %T+ with sort -n. You should use %T@ instead here. Jan 21, 2021 at 16:30
  • Edited again for clarification
    – swifty
    Jan 22, 2021 at 6:47
  • this even works with \t no need for \0
    – alecxs
    Jan 22, 2021 at 9:06
1

Assuming paths with no newline characters:

ls -ltd "$PWD/relative_path/"* | grep -v '^d'

If you want to list files in the current directory, just drop /relative_path. Obviously, you can also give the absolute path right away:

ls -ltd "/var/reports/"* | grep -v '^d'

And to list dotfiles too, in Bash and Ksh you can simply substitute the * by {*,.*}. In Zsh you would need to setopt cshnullglob first or the command would fail if either dotfiles or non-dotfiles didn't exist in the directory.

Adapted from https://stackoverflow.com/a/5580868.

5
  • Strictly speaking, the GNU specific parts here could be the grep -v '^d' which per POSIX gives unspecified result on non-text (and file names are not guaranteed to be made of text). {*,.*} is a csh-ism but wouldn't work as well in shells other than csh (or zsh -o cshnullglob). Jan 21, 2021 at 16:20
  • @StéphaneChazelas Hmm, {*,.*} works in Bash, Ksh, Zsh too.
    – Quasímodo
    Jan 22, 2021 at 12:17
  • but differently. For instance, in zsh, unless you set the cshnullglob option, it will fail the command if there's either no hidden file or no non-hidden file. Many shells will include . and .. which you don't want. Actually, the shell where it works best is fish here (or zsh -o cshnullglob) rather than csh (which includes . and ..). You can shorten it to {,.}*. In zsh, you'd use *(D). Jan 22, 2021 at 12:28
  • @StéphaneChazelas Thanks for you perseverance on explaining a lot of things, much appreciated. I think an error message if the directory is empty is acceptable, otherwise I have added your suggestion for Zsh.
    – Quasímodo
    Jan 22, 2021 at 12:38
  • (in bash, you'd also need to disable failglob if enabled (bash has no equivalent to cshnullglob and its failglob takes precedence over nullglob, so like in all Bourn-like or rc-like shells, non-matching globs would be passed unexpanded to ls causing error)). Jan 22, 2021 at 13:06

You must log in to answer this question.

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