0

I am trying to run a for loop but trying to exclude files with a specific pattern in the filename. This is the command I am using:

for file in /home/ubuntu/discovery/download/*![.en].mp4; do

I would like this filename to be included:

Blub - S03E10 - Nervous Breakdown.mp4

but this filename to be excluded

Blub - S03E10 - Nervous Breakdown.en.mp4

Can't get it to work. What am I doing wrong?

Thanks in advance

khofm
  • 139
  • 4
  • I would suggest you use `find` to generate a list of desired files (sans exclusions) and then feed this list to a `while/read` loop, eg, `while read -r fname; do do_some_stuff_with_fname; done < <(find /home/unbuntu/discovery/download ... exclude_some_file_types ...)` – markp-fuso Mar 30 '23 at 18:33
  • @markp-fuso Syntaxe of questioni is close than correct! See [my answer](https://stackoverflow.com/a/75891852/1765658)! – F. Hauri - Give Up GitHub Mar 30 '23 at 18:48

4 Answers4

2

What am I doing wrong?

Standard globbing has no grouping or group negation operators (though the extended version has these). In your particular context, I would just filter out the unwanted files inside the loop:

for file in /home/ubuntu/discovery/download/*.mp4; do
  case $file in
    *.en.mp4) continue;;
  esac

  # ...
done

And that should work in any Bourne-family shell, not just Bash.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
1

Pathname Expansion: "match not", with extglob enabled:

         !(pattern-list)
                Matches anything except one of the given patterns

Try this:

for file in /home/ubuntu/discovery/download/!(*.en).mp4; do
    ...
F. Hauri - Give Up GitHub
  • 64,122
  • 17
  • 116
  • 137
1

Another alternative could be:

shopt -s nullglob
for file in /home/ubuntu/discovery/download/*{[^n],[^e]n,[^.]en}.mp4
do
# ...
done
M. Nejat Aydin
  • 9,597
  • 1
  • 7
  • 17
0

Another approach is to iterate over all files, skipping any that have undesirable name patterns. Just make sure to also handle the case where no files are found, because in that case, file is set equal to the glob pattern. Often you can handle that situation by verifying that the path in file actually exists (-e "${file}").

for file in /home/ubuntu/discovery/download/*.mp4; do
    [[ -e "${file}" && "${file}" != *.en.mp4 ]] || continue
    echo ${file}
done
Sanford Freedman
  • 156
  • 1
  • 11