1

I have, e.g., in the directory /etc/ files without extension and with extension

/etc/profile

/etc/profile.1

/etc/profile.2

and there is a directory given by the system containig some files:

/etc/profile.d/file1

/etc/profile.d/file2

/etc/profile.d/file3

In a script I would like to specify that ls lists all my profile* files but not the files in the directory which begins with the same name as my files.

If the dir name "/etc/profile.d/" will be listed is not important, but the files under this dir should not be listed.

This my wish is according to what the manpage says, that ls will only work recursively if the option "-R" is given.

I want to use ls because its sorting capabilities and because ls can show modification, access and creation times, etc.

Normaly I would use this command:

ls -la --time-style=long-iso /etc/profile*

but this not only shows my files, ls goes down into the directory /etc/profile.d and lists the files in this dir too.

I am interested in a general solution, not only for the given names in this example.

Regards

Anton_Wessel@t-online.de

2 Answers2

2

That's what ls is for, it lists the contents of directories.

If passed files that are not directories, it lists those files instead. In order to get that behaviour for files of type directory as well, you need to pass the -d option in which case it lists the directory files themselves instead of their contents:

ls -l -d --time-style=long-iso /etc/profile*

I removed -a as it's only relevant when ls lists the contents of directories (as opposed to the directories themselves whose list is passed to ls by the shell after expanding the glob).

It's important to realise that above, it's not ls that generates the list of files, it's the shell that expands /etc/profile* to the list of matching files.

You almost always want to use -d when passing glob expansions to ls.

If using zsh, you can use its stat builtin to retrieve metadata from the files:

$ zmodload zsh/stat
$ stat -LF %FT%T.%N%z +mtime /etc/profile*
/etc/profile 2021-04-10T21:00:00.000000000+0100
/etc/profile.d 2022-09-22T17:26:49.109271759+0100

(here using a non-ambiguous date format).

Like ls's output, that's still unprocessable in the face of file names with newline characters. You can however store the result in an array instead of displaying it:

stat -nA mtimes -LF %FT%T.%N%z +mtime /etc/profile*

And then loop on it with:

for file mtime ($mtimes) print -r -- ${(q+)file} was last modified on $mtime

Or

printf '%q was last modified on %s\n' $mtimes

Or call one stat per file, getting the result into an associative array for instance:

for file (/etc/profile*)
  stat -LH s -F %FT%T.%N%z -- $file &&
    print -r -- $file, $s[size] bytes big was last modified on $s[mtime]
  • Just to be specific, l -a is to list hidden files in the current or itemized directories. Since you have specified a pattern which is not for hidden files, it is irrelevant to your pattern match. – Eric Marceau Sep 22 '22 at 19:08
  • @EricMarceau, No. Even in ls -ld .* it would be irrelevant, -a is for ls not to skip the hidden files in the directories whose contents it lists. With -d, it lists directories, not their contents. – Stéphane Chazelas Sep 22 '22 at 19:09
  • Just addressing the specific usage of -a regarding the hidden files. I did not say anything to contradict what you said regarding ls -d {pattern}* . – Eric Marceau Sep 22 '22 at 19:26
  • @EricMarceau, I'm just saying your Since you have specified a pattern which is not for hidden files is at best misleading. -a is irrelevant with -d whether the pattern matches hidden files or not. – Stéphane Chazelas Sep 22 '22 at 19:32
  • "-a" is meant to display what ls does not display by default. If the pattern is ".{pat}*", then that specification will display hidden files by default, overriding the non "-a" behaviour, so again, -a is irrelevant. I don't understand why you take issue with my statement. – Eric Marceau Sep 22 '22 at 19:37
-1

How about find?

find /etc -maxdepth 1 -name "profile*" -type f
White Owl
  • 5,129