hc0re
hc0re

Reputation: 1986

IFfing through two (or more) folders to find files matching pattern

I have a bash-related question. To start the explanation. I had a folder structure looking like this:

config--
       |-config-chain.conf
       |-somefile1.txt
       |-somefile2.txt
       |-somefile3.txt
       |-somefile4.txt
       |-somefile5.txt
       |-somefile6.txt 

config-chain.conf contains text looking like this:

somefile1
somefile2
somefile3
somefile4
somefile5
somefile6

Before today, all those txt files were in one folder, so iterating through this was simple.

But the specification has changed and I have to do this the new way.

config--
       |-config-chain.conf
       |
       |--folder1--
                  |-somefile1.txt
                  |-somefile2.txt
                  |-somefile3.txt
       |--folder2--
                  |-somefile4.txt
                  |-somefile5.txt
                  |-somefile6.txt

Before that, I was iterating through this with a simple loop. It looked like this:

while read config-chain
do
    if [ -f $config-chain.txt ];
    then
        echo "Config file found"
    else
        echo "Config file not found"
    fi
done < config-chain.conf

But now the files are in two different folders. My actual approach is looking like this:

while read config-chain
do
    if [ -f folder1/$config-chain.txt ] || [ -f folder2/$config-chain.txt ];
    then
        echo "Config file found"
    else
        echo "Config file not found"
    fi
done < config-chain.conf

It is looking ugly for me, cause I'm looking for the existence of a file in both folders. I don't know how this will look in the future, maybe there will be 15 folders, so imagine this OR with 15 statements... Is there a way to do this cleaner? Maybe with find? Or a more clean way to do this with IF?

Upvotes: 0

Views: 32

Answers (3)

F. Hauri  - Give Up GitHub
F. Hauri - Give Up GitHub

Reputation: 70752

globbing and globstar under

There is my demo:

mkdir config{,/folder{1,2}}
touch config/{{,folder{1,2}}/somefile1,folder{1,2}/somefile2,folder1/somefile{3,4},folder2/somefile{5,6}}

This would create required situation:

ls -lR
.:
total 4
drwxr-xr-x 4 user user 4096 déc 29 11:13 config

./config:
total 8
drwxr-xr-x 2 user user 4096 déc 29 11:13 folder1
drwxr-xr-x 2 user user 4096 déc 29 11:13 folder2
-rw-r--r-- 1 user user    0 déc 29 11:13 somefile1

./config/folder1:
total 0
-rw-r--r-- 1 user user 0 déc 29 11:13 somefile1
-rw-r--r-- 1 user user 0 déc 29 11:13 somefile2
-rw-r--r-- 1 user user 0 déc 29 11:13 somefile3
-rw-r--r-- 1 user user 0 déc 29 11:13 somefile4


./config/folder2:
total 0
-rw-r--r-- 1 user user 0 déc 29 11:13 somefile1
-rw-r--r-- 1 user user 0 déc 29 11:13 somefile2
-rw-r--r-- 1 user user 0 déc 29 11:13 somefile5
-rw-r--r-- 1 user user 0 déc 29 11:13 somefile6

Than now:

while read config_chain ;do
    cfgfile=(config/**/$config_chain)
    echo ${cfgfile[*]}
  done < <(seq -f somefile%g 1 7)
config/folder1/somefile1 config/folder2/somefile1
config/folder1/somefile2 config/folder2/somefile2
config/folder1/somefile3
config/folder1/somefile4
config/folder2/somefile5
config/folder2/somefile6
config/**/somefile7

There is one file missing!!

shopt -s globstar
while read config_chain ;do
    cfgfile=(config/**/$config_chain)
        echo ${cfgfile[*]}
  done < <(seq -f somefile%g 1 7)
config/folder1/somefile1 config/folder2/somefile1 config/somefile1
config/folder1/somefile2 config/folder2/somefile2
config/folder1/somefile3
config/folder1/somefile4
config/folder2/somefile5
config/folder2/somefile6
config/**/somefile7

Well there it is! Than now:

while read config_chain ;do
    for cfgfile in config/**/$config_chain;do
        if [ -f $cfgfile ] ;then
            echo $cfgfile
          fi
      done
  done < <(seq -f somefile%g 1 7)
config/folder1/somefile1
config/folder2/somefile1
config/somefile1
config/folder1/somefile2
config/folder2/somefile2
config/folder1/somefile3
config/folder1/somefile4
config/folder2/somefile5
config/folder2/somefile6

Upvotes: 2

Hans Kl&#252;nder
Hans Kl&#252;nder

Reputation: 2292

dziki, Please note that bash won't accept a '-' as part of a variable name, but it will accept a '_'. Thus

read config_chain

will work much better than

read config-chain

Using the underscore would also allow you to replace

"config-chain.txt"

by

"$config_chain.txt"

in the answers of almas shaikh and F. Hauri, which in all other respects works fine.

Upvotes: 0

SMA
SMA

Reputation: 37023

Yeah you could use find command like below:

filePath=$(find parentDir -name "config-chain.txt")
if [ -z "$filePath" ]
then 
    echo "Config file not found"
else
    echo "Config file found"
fi

And in your while loop you could use $filePath instead of config-chain.conf to get input from.

Upvotes: 1

Related Questions