2

So I am trying to write a command line shell script or a shell script that will be able to recursively loop through a directory, all its files, and sub-directories for certain files and then print the location of these files to a text file.

I know that this is possible using BASH commands such as find, locate, exec, and >. This is what I have so far. find <top-directory> -name '*.class' -exec locate {} > location.txt \;

This does not work though. Can any BASH, Shell scripting experts help me out please?

Thank-you for reading this.

2
  • 1
    Do you want to get absolute path to each found file? Commented Jul 6, 2014 at 22:14
  • 1
    Yes, that would be awesome - because then I would know exactly where it is. :D Commented Jul 6, 2014 at 22:16

3 Answers 3

1

The default behavior of find (if you don't specify any other action) is to print the filename. So you can simply do:

find <top-directory> -name '*.class' > location.txt

Or if you want to be explicit about it:

find <top-directory> -name '*.class' -print > location.txt
Sign up to request clarification or add additional context in comments.

11 Comments

will it loop through all the files and sub-directories for any .class files though or just stop at the first one it finds? Thank-you for the quick answer btw. :D
It gives relative path - not absolute which is what the OP is looking for
@user3808269 It will list all matching files in all subdirectories. And if you run the find command with a absolute path, it will print absolute paths. If you start it with a relative path, it will print relative paths.
...well, if you want an absolute path, just make it find "$PWD/dir".
Oh wow. This works. Thanks pdw and @CharlesDuffy for the help
|
0

You can save the redirection by using find's -fprint option:

find <top-directory>  -name '*.class' -fprint location.txt

From the man page:

-fprint file [...] print the full file name into file file. If file does not exist when find is run, it is created; if it does exist, it is truncated.

4 Comments

That's a GNU extension -- not available in find implementations that only comply with the POSIX standard: pubs.opengroup.org/onlinepubs/009695399/utilities/find.html
I voted for Akos for the answer because this user has much fewer points and had some clearer syntax with the <top-directory> part of the script. Also, I was unaware of the -fprint option before this. Thanks er'body especially @pdw . :D
I like how fprint saves time with not having to create a file. with cat or touch.
@user3808269, you don't need to use cat or touch regardless (particularly not cat, which doesn't actually create files at all); >location.txt creates the file as-is.
0

A less preferred way to do it is to use ls:

ls -d $PWD**/* | grep class

let's break it down:

ls -d # lists the directory (returns `.`)
ls -d $PWD # lists the directory - but this time $PWD will provide full path
ls -d $PWD/** # list the directory with full-path and every file under this directory (not recursively) - an effect which is due to `/**` part
ls -d $PWD/**/* # same like previous one, only that now do it recursively to the folders below (achieved by adding the `/*` at the end)

A better way of doing it:

After reading this due to recommendation from Charles Duffy, it appears as a bad idea to use both ls as well as find (article also says: "find is just as bad as ls in this context".) The reason it's a bad idea is because you can't control the output of ls: for example, you can't configure ls to terminate filenames with NUL. The reason it's problematic is that unix allows all kind of weird characters in a file-name (newline, pipe etc) and will "break" ls in a way you can't anticipate.

Better use a shell script for the task, and it's pretty simple task too:

Create a file my_script.sh, edit the file to contain:

for i in **/*; do
    echo $PWD/$i
done

Give it execute permissions (by running: chmod +x my_script.sh).

Run it from the same directory with:

./my_script.sh

and you're good to go!

9 Comments

what does the -1 one do in this script? Where is the directory to be searched through specified? Thanks for the reply. Interesting.
@user3808269 good catch, I was playing with it and forgot to remove the -1. I'll add explanation in the answer for the rest.
-1; read mywiki.wooledge.org/ParsingLs for a detailed description of why ls should never be used programatically.
@CharlesDuffy thanks for the link - I'll read it right after I tuck the kids in to bed.
@CharlesDuffy thanks for the link! I updated my answer, do you mind having a look and give your review, I'm not a such a great shell-script writer and would appreciate your thoughts.
|

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.