1

I have written a code to search for a word recursively with a file system and all it's subdirectories. While it works for the most part, it is having trouble searching folders that contain spaces, e.g. it will find the search word within a directory "Bash_Exercises" but not "Bash Exercises". I know, from the courses I have taken in Bash, it has something to do with utilizing "" to recognize the entire string, but no matter where I put the "" I can't seem to search the folders that have spaces in their name. I figured that I am overlooking something so small, and just wanted a second pair of eyes.

#! /bin/bash

# Navigate to the home directory

cd /Users/michael/desktop

# Ask for word to search

read -p "What word would you like to search for? " word
echo ""

#Find all directories

for i in $(find . -type d)

do

#In each directory execute the following

    #In each directory run a loop on all contents

    for myfile in "$i"/* ; 
    do

        #If myfile is a file, not a directory or a shell script, echo the file name and line number

        if [[ -f "$myfile" ]]; then

            #Store grep within the varible check

            check=$(grep -ni "$word" "$myfile")

            #Use an if to see if the variable "check" is empty, indicating the search word was not found

            if [[ -n $check ]]; then

                #If check is not empty, echo the folder location, the file name within the folder, and the line where the text shows up

                echo "File location: $myfile"
                echo "$check"
                echo ""
                echo "------------------------"
                echo ""

            fi

        fi

    done

done

Just as a frame of reference, I am very new to Bash, all self taught through online courses, which can only help so much until you get into non-course examples. I appreciate any and all help.

5
  • 1
    So you are reinventing grep -r? Commented Mar 10, 2020 at 16:47
  • 1
    ShellCheck points out that your for i in $(find . -type d) loop is fragile in this respect, and that you should use a while read loop to consume find output instead Commented Mar 10, 2020 at 16:48
  • As @KamilCuk said, functionally you can simply use grep -r <word> directory to find the word in any file that is under that subdirectory's tree. If you are trying to do this as an exercise :) then there are other interesting ways Commented Mar 10, 2020 at 17:09
  • See Bash Pitfalls #1 (for f in $(ls *.mp3)). Commented Mar 10, 2020 at 19:04
  • Also, see BashFAQ #20: How can I find and safely handle file names containing newlines, spaces or both? Commented Mar 11, 2020 at 2:12

1 Answer 1

3

for i in $(find . -type d)

Each time you see for i in $(...) most probably you are making a mistake. The proper way to iterate over list line by line is to use a while read loop:

find . -type d | while IFS= read -r i; do
   : ....
done 

But it's way better to use bash and zero terminated list, in case you have newline character in filenames:

find . -type d -print0 | while IFS= read -d '' -r i; do

More information could be found at bashfaq how to read a stream line by line.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.