How to take backup of a file using find command - unix

I have a file "backup". I want to find that particular file and take a backup with cp command and the backup file will be "backup_b".
The code which i am executing is below
find /u01/app/gafmbs/backup_b -exec cp backup_b backup
But this is not working. How will i do that? Can anybody help me out?

You are not invoking find correctly.
A fix:
find /u01/app/gafmbs -name backup_b -exec cp {} backup \;
^ ^ ^ ^
| | | |
where to look | | exec command terminator
what to look for |
paths to found files

Related

How can I make this find command work recursively in the current directory?

I have this find command and need to make it work recursively in the current directory ( at the moment it searches all the files on the disk )
find . -name ‘OldName*’ -print0 | xargs -0 rename -S ‘OldName’ ‘NewName’
Any idea how to make it search in the current directory that I am navigated to in terminal ?
Would this work?
find . -name 'OldName' -exec rename -n 'OldName' 'NewName' \;

bash find with two commands in an exec ~ How to find a specific Java class within a set of JARs

My use case is I want to search a collection of JARs for a specific class file. More specifically, I want to search recursively within a directory for all *.jar files, then list their contents, looking for a specific class file.
So this is what I have so far:
find . -name *.jar -type f -exec echo {} \; -exec jar tf {} \;
This will list the contents of all JAR files found recursively. I want to put a grep within the seconed exec because I want the second exec to only print the contents of the JAR that grep matches.
If I just put a pipe and pipe it all to grep afterward, like:
find . -name *.jar -type f -exec echo {} \; -exec jar tf {} \; | grep $CLASSNAME
Then I lose the output of the first exec, which tells me where the class file is (the name of JAR file is likely to not match the class file name).
So if there was a way for the exec to run two commands, like:
-exec "jar tf {} | grep $CLASSNAME" \;
Then this would work. Using a grep $(...) in the exec command wouldn't work because I need the {} from the find to take the place of the file that was found.
Is this possible?
(Also I am open to other ways of doing this, but the command line is preferred.)
i find it difficult to execute multiple commands within find-exec, so i usually only grab the results with find and loop around the results.
maybe something like this might help?
find . -type f -name *.jar | while read jarfile; do echo $jarfile; jar tf $jarfile; done
I figured it out - still using "one" command. What I was looking for was actually answered in the question How to use pipe within -exec in find. What I have to do is use a shell command with my exec. This ends up making the command look like:
find . -name *.jar -type f -exec echo {} \; -exec sh -c "jar tf {} | grep --color $CLASSNAME" \;
The --color will help the final result to stick out while the command is recursively listing all JAR files.
A couple points:
This assumes I have a $CLASSNAME set. The class name has to appear as it would in a JAR, not within a Java package. So com.ibm.json.java.JSONObject would become com/ibm/json/java/JSONObject.class.
This requires a JDK - that is where we get the jar command. The JDK must be accessible on the system path. If you have a JDK that is not on the system path, you can set an environment variable, such as JAR to point to the jar executable. I am running this from cygwin, so it turns out my jar installation is within the "Program Files" directory. The presence of a space breaks this, so I have to add these two commands:
export JAR=/cygdrive/c/Program\ Files/Java/jdk1.8.0_65/bin/jar
find . -name *.jar -type f -exec echo {} \; -exec sh -c "\"$JAR\" tf {} | grep --color $CLASSNAME" \;
The $JAR in the shell command must be escaped otherwise the terminal will not know what to do with the space in "Program Files".

Find and replace files from one directory to another WordPress

A site I now manage I found has been corrupted. I would like to keep the content in place, but copy all of the php, txt, and css files from a temporary WordPress installation and move them to the corresponding location using a script.
I don't know how to make a bash or shell script that does something like this:
#!/usr/bash
type = [*\.php|*\.css|*\.ini|*\.txt]
find /temporary/WordPress/ -type f -name '$type' {} + > file-paths-in-temporary-wordpress ;
egrep -o '[a-zA-Z]\.[php|css|ini|txt]' file-paths-in-temporary-wordpress > file-names-of-temporary-WordPress-Installation
find /old/installation/WordPress -type f -name '$type' {} + > file-paths-to-use-as-reference
while read $type in file-names-of-temporary-WordPress-Installation ; do
// locating file-names-of-temporary-WordPress-Installation in old WordPress site, copy files from file-paths-in-temporary-wordpress to the matching locations in the old WordPress installation //
I am confused about how to get this to work. Obviously, this is sorely incomplete.
My desired outcome is to have all of the php, ini, css, and txt files from the fresh WordPress installation copied to the corresponding location at the old WordPress site.
I can use:
find /temporary/WordPress -type f -name '*.php' -exec cp -fvr {} /old/WordPress/Installation/ + ;
find /temporary/WordPress -type f -name '*.css' -exec cp -fvr {} /old/WordPress/Installation/ + ;
..etc.
Any thoughts?
Please help. Thank you!
Why can't you just search each directory and copy if there is a match?
cp /temorary/WordPress/*.php /new/directory/
cp /temporary/WordPress/*.css /new/directory/
...
You can copy everything first and remove things you do not need:
cp -r /temporary/WordPress /old/WordPress/
find /old/WordPress/ -type f -regex ".*\.\(php\|css\|ini\|txt\)" -exec rm {} \;
This might leave empty directories and is fixing things that went wrong (copying files you do not want).
So the right approach is only copying files you need. First go to /temporary/WordPress so you do not need to cut off that dir:
cd /temporary/WordPress
find . -type f -regex ".*\.\(php\|css\|ini\|txt\)" | while read file; do
dir="/old/WordPress/${file%/*}"
mkdir -p "${dir}" 2>/dev/null
cp "${file}" "/old/WordPress/${file}"
done
(Sorry, not tested)

unix: execute gnuplut in different directories using find | xargs

I'm pretty new to using the shell. I have many gnuplot scripts in subdirectories. These include relative paths of the input files. So to execute them in the right way I have to go to the parent directory of the script and then execute it. Is there a way to do this with a find | xargs combination?
find . -name "*gpf" | xargs -i{} dirname {}
is something that I found so far. But I don't know how to go now to the parent directory and then exegute gnuplot right there. Is there a way to do this?
Many thanks.
Edit: Anyone else having any ideas that could help me with this issue? Would really help me a lot! Thanks in advance.
You can try to execute gnuplot with the -exec option of find:
find . -name "*.gpf" -exec gnuplot \{\} \;
Use GNU Parallel:
find . -name "*gpf" | parallel "cd {//};gnuplot {/}"
Learn more about GNU Parallel: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
10 second installation:
wget pi.dk/3 -qO - | sh -x

Why doesn't my 'find' work like I expect using -exec?

I'm trying to remove all the .svn directories from a working directory.
I thought I would just use find and rm like this:
find . -iname .svn -exec 'rm -rf {}' \;
But the result is:
find: rm -rf ./src/.svn: No such file or directory
Obviously the file exists, or find wouldn't find it... What am I missing?
You shouldn't put the rm -rf {} in single quotes.
As you've quoted it the shell is treating all of the arguments to -exec it as a command rather than a command plus arguments, so it's looking for a file called "rm -rf ./src/.svn" and not finding it.
Try:
find . -iname .svn -exec rm -rf {} \;
Just by-the-bye, you should probably get out of the habit of using -exec for things that can be done to multiple files at once. For instance, I would write that out of habit as
find . -iname .svn -print | xargs rm -rf
or, since I'm now using a Macintosh and more likely to encounter file or directory names with spaces in them
find . -iname .svn -print0 | xargs -0 rm -rf
"xargs" makes sure that "rm" is invoked only once every "N" files, where "N" is usually 20. That's not a huge win in this case, because rm is small, but if the program you wanted to execute on every file was large or did a lot of processing on start up, it could make things a lot faster.
maybe its just me, but the old find & rm script does not work on my current config, a la:
find /data/bin/test -type d -mtime +10 -name "[0-9]*" -exec rm -rf {} \;
whereas the xargs solution does, a la:
find /data/bin/test -type d -mtime +10 -name '[0-9]*' -print | xargs rm -rf ;
no idea why, but i've updated my scriptLib so i dont spend another couple hours beating
my head on something so simple....
(running RHEL under kernel-2.6.18-194.11.3.el5)
EDIT: found out why - my RHEL distro defaults vi to insert the dreaded cr into line breaks (whch breaks the command) - following suggestions from nx5000 & jliagre at linuxquestions.org, added the following to ~/.vimrc:
:set fileformat=unix
map <F4> :set fileformat=unix<CR>
map <F5> :set fileformat=dos<CR>
which allows the behavior to pivot on the F4/F5.
to check whether CR's are embedded in your file:
head -1 scriptFile.sh | od -c | head -1
http://www.linuxquestions.org/questions/linux-general-1/bad-interpreter-no-such-file-or-directory-213617/
You can also use the svn command as follows:
svn export <url-to-repo> <dest-path>
Look here for more info.
Try
find . -iname .svn -exec rm -rf {} \;
and that probably ought to work IIRC.
You can pass anything you want in quotes, with the following trick.
find . -iname .svn -exec bash -c 'rm -rf {}' \;
The exec option will be happy to see that you're simply calling an executable with an argument, but your argument will be able to contain a script of basically any size and shape.
find . -iname .svn -exec bash -c '
ls -l "{}" | wc -l
' \;

Resources