Copy modified files with directory structure in linux - linux

How can I copy a list of files modified today with the directory structure into a new directory. As shown in the following command I want to copy all the files modified today from /dev1/Java/src into /dev2/java/src. The src folder has many sub directories.
find /dev1/Java/src -newermt 2014-06-10 > 1.txt
for f in $(cat 1.txt) ; do cp $f /dev2/Java/src; done

You can take advantage of find and cpio utility.
cd /dev1/Java/src; find . -mindepth 1 -mtime -1 | cpio -pdmuv /dev2/Java/src
The above command goes to the source directory and finds the list of new files relative to the source directory.
The output is read by cpio and copies the files into the target directory in the same structure as the source, hence the need for relative pathnames.

Extracts the files modified within a day and copies them to the desired path.
find . -type f -mtime -1 -exec cp {} /path \;

Related

copying files from etc ending with digit to test1 directory

I'm new to linux and as an exercice I need to copy the "etc" files that end with a digit from home directory to the test1 directory
(with one command).
I tried this but it dosn't work
find /etc -type f -iname "*[3-9]" -exec cp {} ../test1/ \;
this should work for your home directory files ending with digit
mv `ls . |grep -Eo "^.*[0-9]$"` your-directory
lets says in the current directory you have some files like ofjweifhwef9 or kfhiofeh8 ( files ending with digit)
so ls will list them.
this grep expression "^.*[0-9]$"` will find only files ending with digit. ( because in your home directory system wont allow to have a file like this "/etc/somefile123")
and then mv will move those files to your-directory
note :- if grep cannot find the files ending with number you will see an error ofcourse because mv needs 2 operands but since it wasn't there so error.
mv: missing destination file operand after './your-directory'
It is probably because /etc is a link in the system that you're using, and find doesn't seem to consider it a path until you add an extra / at the end. Try this instead:
find /etc/ -type f -iname "*[3-9]" -exec cp {} ../test1/ \;
Notice the /etc/ instead of /etc. I get the same behavior on my Mac where /etc is a link to another directory.
Of course, also make sure that you have files which names end on a digit under the /etc/ directory tree. I have none in my mac. You should get some files when you run:
find /etc/ -type f -iname "*[3-9]"
If you don't, you don't have any files to copy. You may also try: find /etc/ to see all files under the directory tree.
Finally, you may want to add the option: -depth 1 if you only want to copy the files in the /etc/ directory, as opposed to all the files that match in the directory tree under /etc/.

In BASH, how do you reference a directory name in a copy statement of files you recursively "find"

I want to recursively find all files that end with *DETAIL.pdf
Create a new directory (in another drive) for each file with the same name as the original directory
Copy the file into the new directory
I have this as my current attempt:
find . -name \*DETAIL.pdf -type f -not -path "./test2" -exec cp -R {} ./test2 \;
I am struggling to create new directories for all these files by referencing the original directory name of each file.
The example mentions using cp but the question/problem itself does not, so I would suggest just using find and tar. Also, though the question is a little ambiguous as noted in the comments above, the example seems to suggest that the desired output directory is a child of the same directory being searched. Given that:
find . -path "./test2" -prune -o -type f -name '*DETAIL.pdf' -print0 | \
tar c --null --files-from=- | \
tar xC test2
This uses find for file selection, generating a (null-separated) file list, which tar then uses to copy the files, and the second tar will create the relative directories as needed and write the copied files.

find -exec unzip multiple .zip files, each into their own directory where source and destination different

I have a directory that new .zip files get placed every day. I need to find new files within the last day, and unzip the files each into their own directory in a different location. What I have found with a lot of searching almost does this for me.
find /source1/source2/source3 -maxdepth 1 -type f -mtime -1 \
-exec sh -c 'unzip -d /dest1/dest2/"${1%.*}" "$1"' _ {}
The problem with the above line, is the destination directory it is trying to create is /dest1/dest2/source1/source2/source3/(dir that is the filename of the zip)/{unzipped files} I need it to just be /dest1/dest2/{filename}
Is there a way to strip the source directories out of the ${1%.*} variable? Or if there is a better way to get this done i'm open to any suggestion.
You can strip the source directories with basename. Just replace "${1%.*}" with $(basename "${1%.*}").

Linux: copy ".svn" directories recursively

I know there are dozen of questions about similar topcis but I still can't beat this up.
I need to copy all .svn directories recursively from /var/foo to /var/foo2 on a Debian machine:
/var/www/foo/.svn
/var/www/foo/bar/.svn
...
I tried these two commands without success:
find /var/foo -name ".svn" -type f -exec cp {} ./var/foo2 \;
find /var/foo -name ".svn" -type d -exec cp {} /var/foo2 \;
Once only the svn directory right inside foo is copied, while another time nothing is copied.
Given following file structure:
./
./a/
./a/test/
./a/test/2
./b/
./b/3
./test/
./test/1
Running following script in the directory to be copied:
find -type d -iname test -exec sh -c 'mkdir -p "$(dirname ~/tmp2/{})"; cp -r {}/ ~/tmp2/{}' \;
Should copy all test directories to ~/tmp2/.
Points of interest:
Directories are copied to the destination on a one-by-one basis
Parent directories are created in advance so that cp doesn't complain about target not existing
Rather than just cp, cp -r is used
The whole command is wrapped with sh -c so that operations on {} such as dirname can be performed (so that the shell expands it for each directory separately, rather than expanding it once during calling the find)
Resulting structure in ~/tmp2:
./
./a/
./a/test/
./a/test/2
./test/
./test/1
So all you should need to do is to replace test with .svn and ~/tmp2 with directory of choice. Just remember about running it in the source directory, instead of using absolute paths.
I find that using tar for such operations makes the code often much more readable:
$ mkdir /var/www/foo2
$ cd /var/www/foo2
$ find ../foo/ -type d -name .svn -exec tar c \{\} \+ | \
tar x --strip-components=1
find will list all directories named .svn, and call tar to create (c) an archive file (that is sent to stdout) with all these directories. the archive on stdout is then extracted (x) by another tar instance in the target directory. the relative path portion (../) is automatically removed by the archiving tar, but since we also want to remove the first path component (foo/) we need to add --strip-components.
Note: This will only work if you do not have very many .svn directories you want to copy (more than $(getconf ARG_MAX)-2, which on my system is more than 200000).

copy entire directory excluding a file

As we know, cp -r source_dir intended_new_directory creates a copy of source directory with a new name. Now I want to do the same but want to exclude a particular file. I have found some related answers here, using tar and rsync, but in those solutions I need to create the destination directory first (using mkdir).
I honestly searched a lot, but didn't find exactly what I want.
So far the best I got is this:
tar -c --exclude=\*.dll --exclude=\*.exe sourceDir | tar -x -C destDir
(from http://www.linuxquestions.org/questions/programming-9/how-to-copy-an-entire-directory-structure-except-certain-files-385321/)
If you have binutils, you could use find to filter next cpio to copy (and create directories) :
find <sourceDir> \( ! -name *.dll \) -a \( ! -name *.exe \) | cpio -dumpv <destDir>
Try this by excluding the file using 'grep -v' ->
cp `ls | grep -v <exclude-file>` <dest-dir>
If the directory is not very large I used to write something like this:
src=path/to/source/directory
dst=path/to/destination/directory
find $src -type f | while read f ; do mkdir -p "$dst/`dirname $f`"; cp "$f" "$dst/$f" ; done
Here we list all regular files in $src, iterate over this list and for each file make a directory in $dst if it does not exist yet (-p option of mkdir), then copy the file to that directory.
The above command will copy all the files. Finally, just use
find $src -type f | grep -v whatever | while ...... # same as above
to filter out the files you don't need (e.g. \.bak$, \.orig$, or whatever files you don't want to copy).
Move all exclude file into home or other directory,copy the directory containing all remaining files to the destination folder then restore all exclude files.
#cd mydirectory
#mv exclude1 exclude2 /home/
#cp mydirectory destination_folder/
#cd /home/
#mv eclude1 exclude2 mydirectory/

Resources