0

I have to write a script that prompts the user to enter a filename and then prints all the files on the system with that file name. So far I have this on my script.sh:

#!/bin/bash
echo "please enter filename"
read filename

if [ find . -name $filename ] //not sure if the condition is right
then
    //print all files on the system with that file name 
    not sure what to put here
else
    echo "file does not exist"
fi

Please help, thanks!

4
  • 2
    what happens when you run the script? – jsotola Nov 8 '19 at 6:16
  • @jsotola it will prompt the user to enter a filename such as ".bashrc" or "randomFile" and it will print out all files ending with .bashrc or randomFile.txt, randomFile.whatever – scoobidydoo Nov 8 '19 at 6:31
  • comments in bash start with # – pLumo Nov 8 '19 at 7:46
  • @scoobidydoo, i was not clear in my question ... i did not ask you what you want your script to do ... i asked what happens when you run the script that you posted – jsotola Nov 8 '19 at 21:45
2

You can use something like:

#!/bin/bash
echo "please enter filename"
read filename

find . -name "$filename" | egrep '.*'

if [ "$?" -ne 0 ] 
then
    echo "file does not exist"
fi
1
  • 1
    It would be enough with grep . in place of that egrep, and you could put the pipeline directly in the if statement (no need to look at $?). I would personally get the filename from the command line instead of interactively (this would allow the script to be used in many other situations where interactivity is not an option, such as in cron jobs). – Kusalananda Nov 8 '19 at 7:08
0

For the simple task of finding all files that has a certain name using bash, you don't need find. The find utility is more use useful for instances where you actually need to do operations on the found files.

The bash shell has a special ** pattern that matches "recursively" down into subdirectories. This pattern is enabled by setting the globstar shell option.

#!/bin/bash

shopt -s globstar dotglob nullglob

pathnames=( ./**/"$1" )

if [[ ${#pathnames[@]} -gt 0 ]]; then
    printf 'Found "%s"\n' "${pathnames[@]}"
else
    printf 'Found no file named "%s"\n' "$1"
fi

This would expand the pattern ./**/"$1", which matches all the filenames corresponding to the script's first command line argument anywhere in the current directory or below it. The resulting pathnames are stored in the array pathnames. A test is then carried out on the length of this array, and if it contains something (the array has a length greater than zero), the elements of the array are printed out. If the array is empty, a message to this effect is printed.

The shell options dotglob and nullglob makes sure that shell globbing patterns matches hidden files and that the pattern is completely removed if it doesn't match anything, respectively.

Note that the script (like your attempted code) does not make any distinction between regular files, directories, symbolic links or other types of files.

Testing this script:

$ bash ~/script.sh .zshrc
Found "./.zsh/.zshrc"
Found "./skel/.zshrc"
$ cd /etc
$ bash ~/script.sh .zshrc
Found no file named ".zshrc"

Without this script, setting the failglob and globstar shell options in bash would allow us to do effectively the same thing as the script directly on the command line:

$ shopt -s globstar failglob dotglob
$ echo ./**/.zsh
./.zsh
$ echo ./**/.zshrc
./.zsh/.zshrc ./skel/.zshrc
$ echo ./**/booo
bash: no match: ./**/booo

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.