Home > OS >  Bash - Find files from a specific directory
Bash - Find files from a specific directory

Time:11-13

I am new to bash (but not to programming). I have a bash script that looks for all .txt files in a project

for i in `find . -name "*.txt"`;
do

 basename= "${i}"
 cp ${basename} ./dest
done

However, I would like to get the .txt files only from a specific sub directory. For e.g this is my project structure:

project/
├── controllers/
│   ├── a/
│   │   ├── src/
│   │   │   ├── xxx
│   │   │   └── xxx
│   │   └── files/
│   │       ├── abc.txt
│   │       └── xxxx
│   └── b/
│       ├── src/
│       │   ├── xxx
│       │   └── xxx
│       └── files/
│           ├── abcd.txt
│           └── xxxx
├── lib
└── tests

I would like to get .txt files only from controllers/a/files and controllers/b/files. I tried replacing find . -name "*.txt" with find ./controllers/*/files/*txt, it works fine, but errors out on GitHub actions with No such file or directory found. So I'm looking for a more robust way of finding .txt files from the subdirectory without having to hardcode the path in the for loop. Is that possible?

CodePudding user response:

You can use brace expansion for the search directory, e.g.

find ./project/controllers/{a,b} -type f -name "*.txt"

To select file only below ./project/controllers/a and ./project/controllers/b

Additionally, your use of basename would no longer be needed in your script (and cure the error with the ' ' (space) to the right of the '=' sign. Traditionally in bash, you will use process substitution to feed a while loop rather than using a for loop, e.g.

while read -r fname; do
  # basename="${fname}"     # note! no ' ' on either side of =
  cp -ua "$fname" ./dest
done < <(find ./project/controllers/{a,b} -type f -name "*.txt")

Edit Based On Comment of Many Paths

If you have many controllers not just a and b, then using the -path option instead of the -name options can provide a solution, e.g.

find . -path "./project/controllers/*/files/*.txt" -type f

would select any ".txt" files below any directory below controllers that contains a files directory.

CodePudding user response:

It seems to me what you need is a simple cp command,

cp project/controllers/*/files/*.txt ./dest/

if you want to copy only the files with .txt extension under the directory files (but not in its subdirectories, if any)

  • Related