- How to move or copy files listed by ‘find’ command in unix?
- 5 Answers 5
- Copying multiple specific files from one folder to another
- 7 Answers 7
- Simply copy multiple files at once from command line
- Dealing with duplicates with python
- Notes
- recursively copy files(with same name) to one folder
- 3 Answers 3
- Related
- Hot Network Questions
- Subscribe to RSS
How to move or copy files listed by ‘find’ command in unix?
I have a list of certain files that I see using the command below, but how can I copy those files listed into another folder, say ~/test?
In regards to @EricJablow — you are correct. But also if you run -exec with a +; at the end of the statement it will copy in a single batch and if you use \; it will run a cp command for each file found. Cheers!
5 Answers 5
Adding to Eric Jablow’s answer, here is a possible solution (it worked for me — linux mint 14 /nadia)
find /path/to/search/ -type f -name "glob-to-find-files" | xargs cp -t /target/path/
It looks like xargs is more efficient than exec in situations where copying significant number of files.
Actually, you can process the find command output in a copy command in two ways:
- If the find command’s output doesn’t contain any space, i.e if the filename doesn’t contain a space in it, then you can use:
Syntax: find | xargs cp -t Example: find -mtime -1 -type f | xargs cp -t inner/
Syntax: find -exec cp '<>' \; Example find -mtime -1 -type f -exec cp '<>' inner/ \;
In the second example, the last part, the semi-colon is also considered as part of the find command, and should be escaped before pressing Enter . Otherwise you will get an error something like:
find: missing argument to `-exec'
Copying multiple specific files from one folder to another
I have a large folder of pictures (thousands), and I have a long list of files, by exact file name, that I need to copy to another folder. I want to know if there is a way I can select several specific files from this folder, by name, and copy them to another folder, using the terminal, without copying them individually?
Fyi, for copying specific folders use: cp -rp /copying/from/
7 Answers 7
Simply copy multiple files at once from command line
There are several ways you could achieve this. The easiest I have seen is to use the following.
cp /home/usr/dir/ /home/usr/destination/
The syntax uses the cp command followed by the path to the directory the desired files are located in with all the files you wish to copy wrapped in brackets and separated by commas.
Make sure to note that there are no spaces between the files. The last part of the command, /home/usr/destination/ , is the directory you wish to copy the files into.
or if the all the files have the same prefix but different endings you could do something like this:
Where file1,file2,file3 and file4 would be copied.
From how you worded the question I believe this is what you’re looking for but it also sounds like you might be looking for a command to read from a list of files and copy all of them to a certain directory. If that is the case let me know and i’ll edit my answer.
Dealing with duplicates with python
So I wrote a little python script that I believe should get the job done. However, I am not sure how well versed you are in python (if versed at all) so I will try explaining how to use this script the best I can and please ask as many questions about it as you need.
import os,sys,shutil ### copies a list of files from source. handles duplicates. def rename(file_name, dst, num=1): #splits file name to add number distinction (file_prefix, exstension) = os.path.splitext(file_name) renamed = "%s(%d)%s" % (file_prefix,num,exstension) #checks if renamed file exists. Renames file if it does exist. if os.path.exists(dst + renamed): return rename(file_name, dst, num + 1) else: return renamed def copy_files(src,dst,file_list): for files in file_list: src_file_path = src + files dst_file_path = dst + files if os.path.exists(dst_file_path): new_file_name = rename(files, dst) dst_file_path = dst + new_file_name print "Copying: " + dst_file_path try: shutil.copyfile(src_file_path,dst_file_path) except IOError: print src_file_path + " does not exist" raw_input("Please, press enter to continue.") def read_file(file_name): f = open(file_name) #reads each line of file (f), strips out extra whitespace and #returns list with each line of the file being an element of the list content = [x.strip() for x in f.readlines()] f.close() return content src = sys.argv[1] dst = sys.argv[2] file_with_list = sys.argv[3] copy_files(src,dst,read_file(file_with_list))
This script should be relatively simple to use. First off, copy the above code into the program gedit (should be pre-installed in Ubuntu) or any other text editor.
After that is complete, save the file as move.py in your home directory (it can be any directory but for ease of instruction lets just use the home directory) or add the directory the file is contained in to your PATH. Then cd to your home directory (or whatever directory you saved move.py in) from the terminal and type the following command:
python move.py /path/to/src/ /path/to/dst/ file.txt
This should copy all of the files that are listed from the source directory to the destination directory with duplicates taking the format pic(1).jpg, pic(2).jpg and so on. file.txt should be a file that lists all the pictures you would like to copy with each entry on its own separate line.
In no way should this script effect the source directory, however just make sure to enter the correct paths to the source and destination directory and the worst that could happen is you copy the files to the wrong directory.
Notes
- This script assumes that all of the original pictures are in the same directory. If you want it to check sub directories as well the script will need to be modified.
- If you accidentally mistype a file name, the script will spit out the error
«file does not exist» and prompt you to «press enter» to continue and the script will continue copying the rest of the list. - Don’t forget the trailing / on both the path to the source
directory and path to the destination directory. Otherwise the script will spit an error back at you.
recursively copy files(with same name) to one folder
Implement a simple counter that adds a numeric postfix to each files basename. So you end up with results-001.pdf, results-002.pdf, . Waht is the problem here?
How does the script look like? Usually you can check if the file exists on the target and if yes you rename it (append a number etc).
I just had a simple find code. for file in $(find ./ -name «*.pdf») do cp $file /path/to/your/directory done
3 Answers 3
#!/usr/bin/sh for i in `find -type f` do new=`echo $i|nawk -F"/" '"a[1]"_"$(NF-1)"."a[2]>'` cp $i $new done
A few levels deep within each subfolder of a directory, I have the files spm_2013Jun05.ps.I have been trying to move the files into /home/alistair/Documents/spmresults/. But only two itterations of the same filename have actually copied: -/home/alistair/Documents/spmresults/spm_2013Jun05.ps -/home/alistair/Documents/spmresults/spm_2013Jun05_1.ps for i in $(find ./ -name spm_2013May30.ps -type f) do new= echo $i|nawk -F»/» » cp $i $new done
perhaps something like this will help you find . -type f -exec sh -c ‘if [ ! -e ../aaa/<> ]; then cp <> ../aaa/;else i=0; while [ -e ../aaa/<>_$ ]; do ((i++)); done; cp <> ../aaa/<>_$; fi’ \;
So basically it searches from a current dir, and for any file, it will copy to ../aaa/ dir, if there is already any such file exists, it will append _0 or _1 or . whichever makes it uniq, ideally it should be written in a script and find -exec should call for the script if any further refinement is needed, but i think this one liner should be enough
To rename the files in place as result-0001.pdf , result-0002.pdf etc., so you can move them without any problems:
rename --no-act --verbose 's/.*/sprintf "result-%04d.pdf", ++$main::Mad/e' /path/to/your/directory/results/*/result.pdf
Remove —no-act if you’re happy with the result.
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.13.43531
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.