12

I want to excluse a specific filename (say, fubar.log) from a shell (bash) globbing string, *.log. Nothing of what I tried seems to work, because globbing doesn't use the standard RE set.

Test case : the directory contains

fubar.log
fubaz.log
barbaz.log
text.txt

and only fubaz.log barbaz.log must be expanded by the glob.

Alsciende
  • 26,583
  • 9
  • 51
  • 67
  • possible duplicate of [How can I use inverse or negative wildcards when pattern matching in a unix/linux shell?](http://stackoverflow.com/questions/216995/how-can-i-use-inverse-or-negative-wildcards-when-pattern-matching-in-a-unix-linu) This is a very close subset of the other one. – Ciro Santilli OurBigBook.com Oct 19 '14 at 13:33

2 Answers2

18

if you are using bash

#!/bin/bash
shopt -s extglob
ls !(fubar).log

or without extglob

shopt -u extglob
for file in !(fubar).log
do
  echo "$file"
done

or

for file in *log
do
   case "$file" in
     fubar* ) continue;;
     * ) echo "do your stuff with $file";;
   esac 
done
Servy
  • 202,030
  • 26
  • 332
  • 449
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
  • Thanks! Do you have a solution without extglob? – Alsciende Apr 15 '10 at 09:08
  • 2
    A rejected edit suggested that this is needed in the case without extglob: `shopt -u extglob` I don't have the knowledge to Judge it though. – Dennis Jaheruddin Oct 25 '13 at 10:09
  • `shopt -u extglob` turns off extglobs. Having extglobs turned off doesn't make extglob syntax work, though, so that (now-accepted?) edit looks like a bad one to me -- the `shopt -s extglob` branch of this answer is fine, and so is the `case` statement version, but I'm deeply suspicious of the other. – Charles Duffy Aug 08 '18 at 23:28
2

Why don't you use grep? For example:

ls |grep -v fubar|while read line; do echo "reading $line"; done;

And here is the output:

reading barbaz.log reading fubaz.log reading text.txt

Roger Choi
  • 29
  • 1
  • 1
    Because the glob string is given to a program (logrotate). So I need a glob string. – Alsciende Apr 15 '10 at 09:38
  • 1
    See [Why you shouldn't parse the output of `ls`](http://mywiki.wooledge.org/ParsingLs). Even if you don't have extglobs to do `!(*fubar*)`, less buggy to do it like: `for file in *; [[ $file = *fubar* ]] && continue; echo "Reading $line"; done` – Charles Duffy Aug 08 '18 at 16:42