I have a simple script that I understand most of, it’s the find command that’s unclear. I’ve got a lot of documentation but it’s not serving to make it much clearer. My thought is that it is working like a for-loop, the currently found file is swapped in for {} and copied to $HOME/$dir_name, but how does the search with -path and -prune -o work? It’s annoying to have such specific and relevant documentation and still not know what’s going on.
#!/bin/bash
# The files will be search on from the user's home
# directory and can only be backed up to a directory
# within $HOME
read -p "Which file types do you want to backup " file_suffix
read -p "Which directory do you want to backup to " dir_name
# The next lines creates the directory if it does not exist
test -d $HOME/$dir_name || mkdir -m 700 $HOME/$dir_name
# The find command will copy files that match the
# search criteria ie .sh . The -path, -prune and -o
# options are to exclude the backdirectory from the
# backup.
find $HOME -path $HOME/$dir_name -prune -o
-name "*$file_suffix" -exec cp {} $HOME/$dir_name/ ;
exit 0
This is just the documentation that I know I should be able to figure this out from.
-path pattern
File name matches shell pattern pattern. The metacharacters do not treat / or .
specially; so, for example,
find . -path “./sr*sc”
will print an entry for a directory called ./src/misc (if one exists). To ignore a
whole directory tree, use -prune rather than checking every file in the tree. For
example, to skip the directory src/emacs and all files and directories under it, and
print the names of the other files found, do something like this:
find . -path ./src/emacs -prune -o -print
From Findutils manual
— Action: -exec command ;
This insecure variant of the -execdir action is specified by
POSIX. The main difference is that the command is executed in the
directory from which find was invoked, meaning that {} is
expanded to a relative path starting with the name of one of the
starting directories, rather than just the basename of the matched
file.While some implementations of find replace the {} only where
it appears on its own in an argument, GNU find replaces {}
wherever it appears.
And
For example, to compare each C header file in or below the current
directory with the file /tmp/master:find . -name '*.h' -execdir diff -u '{}' /tmp/master ';'
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
-path works exactly like -name, but applies the pattern to the entire pathname of the file being examined, instead of to the last component.
-prune forbids descending below the found file, in case it was a directory.
Putting it all together, the command
find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ ;
- Starts looking for files in
$HOME. - If it finds a file matching
$HOME/$dir_nameit won’t go below it (“prunes” the subdirectory). - Otherwise (
-o) if it finds a file matching*$file_suffixcopies it into$HOME/$dir_name/.
The idea seems to be make a backup of some of the contents of $HOME in a subdirectory of $HOME. The parts with -prune is obviously necessary in order to avoid making backups of backups…
Method 2
It is part of the find command, the -exec statement.
It allows you to interact with the file/directory found by the find command.
find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ ;
find $HOME means find files/directories in $HOME
To understand -path <some_path>, see `find -path` explained
To understand -prune, see https://stackoverflow.com/questions/1489277/how-to-use-prune-option-of-find-in-sh
-o means OR, so -path <some_path> OR -name *$file_suffix
-exec means execute the command.
cp {} $HOME/$dir_name/ copy any files matching to $HOME/$dir_name/
; means terminate the -exec command
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0