124

I would like to run ls and exclude certain files in the output.

When I run the following command, I get all files, each on a separate line:

$ ls -1
file1
file2
file3
temp

I would like to run this command in a way so that it shows:

$ ls -1 <insert magic here> temp
file1
file2
file3
1
  • -1 Force output to be one entry per line. This is the default when output is not to a terminal
    – Timo
    Feb 7, 2023 at 15:56

5 Answers 5

158
ls -I <filename>

-I: Ignore the filename, i.e. don't list the specified file.

To ignore more than one file add a -I before each filename.

ls -I file1 -I file2

To ignore files by their name extensions do the following, for example.

ls -I "*.jpg" -I "*.svg"
3
  • 5
    If you use the long-form option --ignore you can extend that to glob patterns e.g. ls --ignore="file?" or ls --ignore="file*" Aug 18, 2014 at 15:23
  • 3
    you can use glob patterns with the short form as well by quoting the patterns
    – verboze
    Dec 29, 2015 at 5:42
  • 1
    you can even use glob patterns without quotes, but by escaping the special letters: ls -I \*.jpg (tested in bash)
    – HongboZhu
    Jan 15, 2020 at 13:46
28

For me, if I use -I once, it works, but if I use twice it doesn't. E.g:

  • This works:

    ls -I *.csv
    
  • But:

    ls -I *.csv -I *.txt
    

    doesn't work and returns .txt files instead.

--ignore did the trick for me. This is what I needed and worked:

ls -lhrt --ignore="*.gz" --ignore="*.1"

The above will list files from my log folder excluding old backup logs.

2
  • 9
    quoting *.csv in the first form works, e.g.., ls -I '*.txt'. The reason it doesn't work unquoted is because of shell expansion, i.e. you're telling the shell to list all csv files instead of excluding them. What's actually happening is that it ignores the first .csv and .1 files after expansion, but lists the remainders
    – verboze
    Dec 29, 2015 at 5:40
  • 1
    Double-quoting worked for me as well. Thanks @verboze
    – user38537
    Sep 29, 2016 at 20:41
19

You can also use:

ls --ignore={"*.jpg","*.png","*.svg"}
1
  • 9
    This is simply using bash's brace expansion to get three --ignore options. You could have also used --ignore="*."{jpg,png,svg}
    – muru
    Feb 14, 2017 at 0:27
7

I think that this produces the output you're looking for:

ls -1 !(temp)

Apparently, you need shopt -s extglob for that to work (I have it enabled, so I guess some time in the distant past I found it useful and enabled it).

I guess you could also use grep to filter the output:

ls -1 | grep -v '^temp$'

Using a pipe and filters provides a lot more flexibility, and skills that are transferable to other commands/situations, though you might not be interested in that for this specific case.

2

I don't believe anyone else has mentioned the use of the --hide parameter with ls. It can be done as such:

ls --hide=*.jpg

If you want to pass in multiple --hide arguments just do:

ls --hide=*some_pattern* --hide=*some_other_pattern*
2
  • What's so hard to believe? This is pretty much the same as --ignore mentioned in multiple answers.
    – muru
    Dec 14, 2022 at 3:31
  • 1
    When I say "I don't believe" in this scenario of English it means "I don't think". You're thinking of "I can't believe". I am just showing there are other options. :)
    – radhadman
    Jan 3, 2023 at 21:14

You must log in to answer this question.

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