Home > database >  Getting the contents of a directory excluding everything inside .git in bash
Getting the contents of a directory excluding everything inside .git in bash

Time:11-28

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:

  1. To get all the .txt files I use : find . -type f \( -name "*.txt" \). There are no .txt files inside .git so this is working.

  2. 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.

  3. To get all the directories and sub-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
  • Related