Reputation: 41
Trying to figure out how to include all .txt
files except one called manifest.txt
.
FILES=(path/to/*.txt)
Upvotes: 4
Views: 1410
Reputation: 52251
You can use extended glob patterns for this:
shopt -s extglob
files=(path/to/!(manifest).txt)
The !(pattern-list)
pattern matches "anything except one of the given patterns".
Note that this exactly excludes manifest.txt
and nothing else; mmanifest.txt
, for example, would still go in to the array.
As a side note: a glob that matches nothing at all expands to itself (see the manual and this question). This behaviour can be changed using the nullglob
(expand to empty string) and failglob
(print error message) shell options.
Upvotes: 5
Reputation: 103998
I think this is best handled with an associative array even if just one element.
Consider:
$ touch f{1..6}.txt manifest.txt
$ ls *.txt
f1.txt f3.txt f5.txt manifest.txt
f2.txt f4.txt f6.txt
You can create an associative array for the names you wish to exclude:
declare -A exclude
for f in f1.txt f5.txt manifest.txt; do
exclude[$f]=1
done
Then add files to an array that are not in the associative array:
files=()
for fn in *.txt; do
[[ ${exclude[$fn]} ]] && continue
files+=("$fn")
done
$ echo "${files[@]}"
f2.txt f3.txt f4.txt f6.txt
This approach allows any number of exclusions from the list of files.
Upvotes: 1
Reputation: 6995
You can build the array one file at a time, avoiding the file you do not want :
declare -a files=()
for file in /path/to/files/*
do
! [[ -e "$file" ]] || [[ "$file" = */manifest.txt ]] || files+=("$file")
done
Please note that globbing in the for
statement does not cause problems with whitespace (even newlines) in filenames.
EDIT
I added a test for file existence to handle the case where the glob fails and the nullglob
option is not set.
Upvotes: 2
Reputation: 4596
FILES=($(ls /path/to/*.txt | grep -wv '^manifest.txt$'))
Upvotes: 1