I need to get the number of the contents of a directory that is a git repository.
I have to get the number of:
1) Other directories inside the directory I am currently iterating (and the other sub-directories inside them if they exist)
2) .txt files inside the directory and its sub-directories
3) All the non-txt files inside the directory and its sub-directories
In all the above cases I must ignore the .git directory, along with all the files and directories that are inside of it.
Also I must use bash script exclusively. I can't use another programing language.
Right now I am using the following commands to achieve this:
To get all the
.txt
files I use :find . -type f \( -name "*.txt" \)
. There are no.txt
files inside.git
so this is working.To get all the
non-txt
files I use:find . -type f \( ! -name "*.txt" \)
. The problem is that I also get all the files from.git
and I don't know how to ignore them.To get all the
directories
andsub-directories
I use:find . -type d
. I don't know how to ignore the.git
directory and it's sub-directories
CodePudding user response:
The easy way is to just add these extra tests:
find . ! -path './.git/*' ! -path ./.git -type f -name '*.txt'
The problem with this is ./.git
is still traversed, unnecessarily, which takes time.
Instead, -prune
can be used. -prune
is not a test (like -path
, or -type
). It's an action. The action is "don't descend the current path, if it's a directory". It must be used separately to the print action.
# task 1
find . -path './.git' -prune -o -type f -name '*.txt' -print
# task 2
find . -path './.git' -prune -o -type f ! -name '*.txt' -print
# task 3
find . -path './.git' -prune -o -type d -print
- If
-print
isn't specified,./.git
is also printed as the default action. - I used
-path ./.git
, because you said "the.git
directory". If for some reason there are other.git
directories in the tree, they will be traversed and printed. To ignore all directories in the tree named.git
, replace-path ./.git
with-name .git
.
CodePudding user response:
Sometimes writing a bash loop is more clear than a one-liner
for f in $(find .); do
if [[ -d $f && "$f" == "./.git" ]]; then
echo "skipping dir $f";
else
echo "do something with $f";
fi;
done