Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use find to identify filename same as the parent directory name

Tags:

regex

linux

find

I would like to use find in order to search for files in different subdirectories that have to match the same pattern as their parent category.

example:

ls
Random1_fa  Random2_fa  Random3_fa

inside these dirs there are different files that I want to search for only one of each:

cd Random1_fa
Random1.fa
Random1.fastq
Random1_match_genome.fa
Random1_unmatch_genome.fa
...

I want to "find" only the files with "filename".fa e.g:

/foo/bar/1_Random1/Random1_fa/Random1.fa
/foo/bar/2_Random2/Random2_fa/Random2.fa
/foo/bar/3_Random5/Random5_fa/Random5.fa
/foo/bar/10_Random99/Random99_fa/Random99.fa

I did:

ls | sed 's/_fa//' |find -name "*.fa"

but not what I was looking for. I want to redirect the result of sed as a regex pattern in find. Something "awk-like" this:

ls| sed 's/_fa//' |find -name "$1.fa"

or

ls| sed 's/_fa/.fa/' |find -name "$1"
like image 481
K Y Avatar asked Oct 16 '25 19:10

K Y


1 Answers

Why read from standard input using sed to filter out files to exclude when you can do the regex condition directly with find. First you run a shell glob expansion for all directories ending with _fa and get the name of the string to find to use in the find expression. All you need to do is

for dir in ./*_fa; do 
    # Ignore un-expanded globs from the for-loop. The un-expanded string woul fail
    # to match the condition for a directory(-d), so we exit the loop in case
    # we find no files to match
    [ -d "$dir" ] || continue
    # The filename from the glob expansion is returned as './name.fa'. Using the
    # built-in parameter expansion we remove the './' and '_fa' from the name
    str="${dir##./}"
    regex="${str%%_fa}"
    # We then use 'find' to identify the file as 'name.fa' in the directory
    find "$dir" -type f -name "${regex}.fa"
done

The below would match filenames containing only [A-Za-z0-9] and ending with .fa. Run this command at the top level containing your directories to match all the files.

To copy the file elsewhere add the following

find "$dir" -type f -name "${regex}.fa" -exec cp -t /home/destinationPath {} + 
like image 70
Inian Avatar answered Oct 18 '25 11:10

Inian