Find and copy files
If your intent is to copy the found files into /home/shantanu/tosend
, you have the order of the arguments to cp
reversed:
find /home/shantanu/processed/ -name '*2011*.xml' -exec cp "{}" /home/shantanu/tosend \;
Please, note: the find
command use {}
as placeholder for matched file.
find and copy file using Bash
I would recommend using find
's -exec
option:
find . -ctime 15 -exec cp {} ../otherfolder \;
As always, consult the manpage for best results.
How to move or copy files listed by 'find' command in unix?
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/
You can refer to "How can I use xargs to copy files that have spaces and quotes in their names?" as well.
Find and copy specific files by date
Would you please try the following:
#!/bin/bash
dir="/var/www/my_folder"
second=$(ls -t "$dir/"*.log | head -n 2 | tail -n 1)
if [[ $second =~ .*_([0-9]{4}_[0-9]{2}_[0-9]{2})\.log ]]; then
capturedate=${BASH_REMATCH[1]}
cp -p "$dir/"*"$capturedate".dmp /tmp
fi
second=$(ls -t "$dir"/*.log | head -n 2 | tail -n 1)
will pick the
second to last log file. Please note it assumes that the timestamp
of the file is not modified since it is created and the filename
does not contain special characters such as a newline. This is an easy
solution and we may need more improvement for the robustness.- The regex
.*_([0-9]{4}_[0-9]{2}_[0-9]{2})\.log
will match the log
filename. It extracts the date substring (enclosed with the parentheses) and assigns the bash variable${BASH_REMATCH[1]}
to it. - Then the next
cp
command will do the job. Please be cateful
not to include the widlcard*
within the double quotes so that
the wildcard is properly expanded.
FYI here are some alternatives to extract the date string.
With sed
:
capturedate=$(sed -E 's/.*_([0-9]{4}_[0-9]{2}_[0-9]{2})\.log/\1/' <<< "$second")
With parameter expansion of bash (if something
does not include underscores):
capturedate=${second%.log}
capturedate=${capturedate#*_}
With cut
command (if something
does not include underscores):
capturedate=$(cut -d_ -f2,3,4 <<< "${second%.log}")
Find Files Containing Certain String and Copy To Directory Using Linux
Edit: After clearing things up (see comment)...
cp *Qtr_1_results* /data/jobs/file/obj1
What you're doing is just greping for nothing. With ;
you end the command and cp
prints the error message because you only provide the source, not the destination.
What you want to do is the following. First you want to grep for the filename, not the string (which you didn't provide).
grep -l the_string_you_are_looking_for *Qtr_1_results*
The -l
option gives you the filename, instead of the line where the_string_you_are_looking_for
is found. In this case grep
will search in all files where the filename contains Qtr_1_results
.
Then you want send the output of grep
to a while
loop to process it. You do this with a pipe (|
). The semicolon ;
just ends lines.
grep -l the_string_you_are_looking_for *Qtr_1_results* | while read -r filename; do cp $filename /path/to/your/destination/folder; done
In the while
loop read -r
will put the output of grep
into the variable filename
. When you assing a value to a variable you just write the name of the variable. When you want to have the value of the variable, you put a $
in front of it.
how to find and copy files from many sub folders into it's parent folder
..
refers to the parent directory of your current working directory.
To strip off one level of directory structure from the end, try
find . -type f -name "*.jpg" -exec sh -c 'for p; do
cp "$p" "${p%/*/*}"
done' _ {} +
The parameter expansion ${p%pattern}
produces the value of p
with the shortest possible match on pattern
removed from the end of it (or simply returns the original value when the pattern doesn't match).
Because the parameter expansion needs to be evaluated at the time the file name is set, we wrap it in sh -c '...'
and for efficiency, we wrap the operation in a for
loop so that find
can pass in multiple files to a single shell invocation (hence +
instead of \;
at the end).
The _
is just a placeholder which gets assigned to $0
which isn't used at all here.
In the less general case, if you just have a single destination folder, you can hard-code it directly, of course:
find . -type f -name "*.jpg" -exec cp -t sub-1 {} +
Unfortunately, cp -t
is a GNU extension; if your OS doesn't have it, you have to reorganize to something more similar to the above command.
Copy files with date/time range in filename
If your time span is reasonably limited, just inline the acceptable file names into the single find
command.
find . \( -false $(for ((iTime=starttime;iTime<=endtime;iTime++)); do printf ' %s' -o -name "*$iTime*"; done) \) -exec cp --parents \{\} ${dst} \;
The initial -false
predicate inside the parentheses is just to simplify the following predicates so that they can all start with -o -name
.
This could end up with an "argument list too long" error if your list of times is long, though. Perhaps a more robust solution is to pass the time resolution into the command.
find . -type f -exec bash -c '
for f; do
for ((iTime=starttime;iTime<=endtime;iTime++)); do
if [[ $f == *"$iTime"* ]]; then
cp --parents "$f" "$0"
break
fi
done' "$dst" {} +
The script inside -exec
could probably be more elegant; if your file names have reasonably regular format, maybe just extract the timestamp and compare it numerically to check whether it's in range. Perhaps also notice how we abuse the $0
parameter after bash -c '...'
to pass in the value of $dst
.
Recursively find and copy files from many folders
I think this should do what you need assuming they are all .txt files.
import glob
import shutil
filenames_i_want = ['A_010720_X.txt','B_120720_Y.txt']
TargetFolder = r'C:\ELK\LOGS\ATH\DEST'
all_files = []
for directory in ['A', 'B']:
files = glob.glob('C:\{}\*\DL\*.txt'.format(directory))
all_files.append(files)
for file in all_files:
if file in filenames_i_want:
shutil.copy2(file, TargetFolder)
Related Topics
How to Use Local Docker Images With Minikube
More Elegant "Ps Aux | Grep -V Grep"
Using Printf in Assembly Leads to Empty Output When Piping, But Works on the Terminal
Read Values into a Shell Variable from a Pipe
Find and Replace With Sed in Directory and Sub Directories
How to Permanently Export a Variable in Linux
Adding a New Entry to the Path Variable in Zsh
How to Recursively Find All Files in Current and Subfolders Based on Wildcard Matching
What Does "&" At the End of a Linux Command Mean
How to Merge Two Files Using Awk
How to Replace Spaces in File Names Using a Bash Script
Fastest Way to Find Lines of a File from Another Larger File in Bash
Peak Memory Usage of a Linux/Unix Process
How to Get Gcc to Output Raw Binary