15

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

  • 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
23

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.*)
  • 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 9: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 Aug 16 '17 at 9:30
10

You can use grep with the option -v.

ls -lrt | grep -v <exclude-filename-part>
  • 1
    not sure why this was downvoted, it's the correct answer. – Tim Kennedy Oct 16 '12 at 12:21
  • 5
    Doing a grep on ls output is not always correct and is not recommended. It has side effects. Not able to recall exact issues. Side note - down vote was not from me ;) – mtk Oct 16 '12 at 12:28
  • 1
    Here's the link as to why parsing ls is a bad idea. – mtk Oct 18 '12 at 13:28
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 {} +

  • Probably want -maxdepth 1 as well to mimic non-recursive ls. – jw013 Oct 16 '12 at 13:27
  • Nice. Users who have a more minimal POSIX find without -maxdepth should look here. – Wildcard May 12 '16 at 19:52
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.

-1

Just do

ls -ltr `grep -il patterntosearch  *`
  • grep searches for a pattern within a file, rather than in the file name. – evilsoup Jul 23 '13 at 16:53
-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 1 '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 2 '18 at 0:40
  • only with -F, @smokes2345; a period will match any character in a basic regular expression. See: unix.stackexchange.com/q/119905/117549 – Jeff Schaller Mar 2 '18 at 2:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.