Find and Copy Files

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



Leave a reply



Submit