The directory tree is like this:
.
├── A_123
│ └── 123.txt
├── A_456
│ ├── tmp
│ └── tmp.log
└── A_789
└── 789.txt
There're 3 directories (A_123, A_456, A_789).
The pattern of a directory name is: A_{numbers} and the file I'm interested in is {numbers}.txt.
I was wondering whether there's a way to get the directories A_{numbers} that has no {numbers}.txt file in them. For example above, this script should return:
./A_456
as A_456 doesn't have 456.txt in its folder but A_123 and A_789 have their {numbers}.txt files in the relevant folder.
Anyone has ideas about this? Thanks!
Here's one approach:
for dir in *;do
if [ $(find "$dir" -maxdepth 1 -regex '.*/[0-9][0-9]*\.txt' | wc -l) = 0 ]; then
echo $dir
fi
done
Since the A_[0-9] directories are not nested, you can easily do this with a glob in a loop. This implementation is pure bash, and does not spawn in external utilities:
for d in A_[0-9]*/; do # the trailing / causes only directories to be matched
files=("$d"/[0-9]*.txt) # populate an array with matching text files
((!${#files})) && echo "$d" # echo $d if the array is empty
done
There are some problems with this implementation. It will match a file such as "12ab.txt" and requires loading all the filenames for a directory into the array.
Here is another method in bash that does a more accurate filename matching:
re='^[0-9]+[.]txt$'
for d in A_[0-9]*/; do
for f in *; do
if [[ -f $f && $f =~ $re ]]; then
echo "$d"
break
fi
done
done
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With