22

I have a directory in which lots of files (around 200) with the name temp_log.$$ are created with several other important files which I need to check.

How can I easily list out all the files and exclude the temp_log.$$ files from getting displayed?

Expected output

$ ls -lrt <exclude-filename-part>
-- Lists files not matching the above given string

I have gone through ls man page but couldn't find anything in this reference. Please let me know if I have missed any vital information here.

Thanks

mtk
  • 27,530
  • 35
  • 94
  • 130
  • 1
    in BASH, ls --hide='temp_log.$$' should work. You could/should also extend this with wildcards, depending which part of the whole term temp_log.$$ is. – erch Jul 23 '13 at 17:21

6 Answers6

30

With GNU ls (the version on non-embedded Linux and Cygwin, sometimes also found elsewhere), you can exclude some files when listing a directory.

ls -I 'temp_log.*' -lrt

(note the long form of -I is --ignore='temp_log.*')

With zsh, you can let the shell do the filtering. Pass -d to ls so as to avoid listing the contents of matched directories.

setopt extended_glob          # put this in your .zshrc
ls -dltr ^temp_log.*

With ksh, bash or zsh, you can use the ksh filtering syntax. In zsh, run setopt ksh_glob first. In bash, run shopt -s extglob first.

ls -dltr !(temp_log.*)
Sridhar Sarnobat
  • 1,802
  • 20
  • 27
  • Please, not single quotes in the example for GNU ls: ls -I 'temp_log.*' -lrt They are necessary to pass pattern to the command and not let the shell expand it. – shargors Dec 20 '16 at 16:42
  • On Ubuntu bash v4.3.48, it should be -Itemp_log.* without any space after the -I – Yan King Yin Aug 16 '17 at 09:23
  • 1
    @YanKingYin No, it's fine to have a space after the -I. However, the * needs to be quoted one way or another. -I temp_log.* doesn't work but -I 'temp_log.*', -I "temp_log.*", -I temp_log.\*, etc. are fine. – Gilles 'SO- stop being evil' Aug 16 '17 at 09:30
  • Just a side note: for multiple files, consider using multiple -I parameters. Generally, a simple ignore expression (example, -I '*.jar') works fine. But making -I accept an explicit list of files to ignore is hard. Say I must ignore xyz.jar and abc.exe, while reporting all other files in the directory. Then ls -I '(xyz.jar|abc.exe)' doesn't work. But multiple -I parameters work very well: ls -I xyz.jar -I abc.exe. – Happyblue May 21 '21 at 04:03
  • BTW, man ls did not say much about regex support, but then I saw RMS (Stallman) wrote my version of ls. So I checked info ls which states: ‘-I PATTERN’ ... ignore files whose names match the shell pattern (not regular expression) PATTERN. :-) – Happyblue May 21 '21 at 04:05
14

You can use grep with the option -v.

ls -lrt | grep -v <exclude-filename-part>
andrade
  • 366
3

You can use find for this:

find . \! -name 'temp_log*'

This will just print the names, you can add -ls to make a ls -l style output with timestamp and permissions, or use -exec ls {} + to actually pass to ls with whatever options you want for columns, sorting, etc.

I wrote this assuming this was just files in a directory. If the directory contains other directories, you may want to avoid recursively listing them

find . \! -name 'temp_log*' -maxdepth 1

And if you use ls you'll want to pass the -d option to stop it from listing inside the directories: -exec ls -d {} +

Random832
  • 10,666
2

I think you want to use a feature of the shell, not of ls. I use bash, so I checked for what you want in man bash. Search for "^EXPANSION", (by first pressing '/'). Excerpt:

EXPANSION

    Expansion is performed on the command line after it has been split into words.  There are seven kinds of expansion performed: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion.

   ︙
... < snip > ...
   ︙

Pathname Expansion

    After word splitting, unless the -f option has been set, bash scans each word for the characters *, ?, and [.  If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of file names matching the pattern.  …

I've recently started excluding files based on their first letter, with a command like:

$ ls ./[^t]*

This would match anything that doesn't start with the letter t. If you add more characters between the brackets, then you exclude files starting with those letters too.

Looking for a link, and I've a good one! See Pattern Matching. From there, this would work for your case:

$ ls -lrt ./!(temp_log.*)

This requires that the extglob shell option is enabled using the shopt builtin (shopt -s extglob), as stated by Gilles.

Alex Leach
  • 7,910
-1

Just do

ls -ltr `grep -il patterntosearch  *`
rahmu
  • 20,023
-2

Since the files that you DONT want printed have "temp_log." in the filename, then filter out with grep:

ls -lrt | grep -v "temp_log."

NOTE: The other post with a similar answer probably got downvoted because the user didn't include quotes " " around the string that grep should be looking for. Without the the quotes, it doesn't work as advertised.

  • Your 'NOTE' is not strictly correct. There are certain characters that might need to be quoted, but I don't think there are any in that particular string. – smokes2345 Mar 01 '18 at 22:00
  • until there's a user or group named "temp_log" (the dot in regex would match a space or anything following temp_log. This is not a good (general) way to exclude ls results. – Jeff Schaller Mar 02 '18 at 00:40
  • only with -F, @smokes2345; a period will match any character in a basic regular expression. See: https://unix.stackexchange.com/q/119905/117549 – Jeff Schaller Mar 02 '18 at 02:31