Copy files with find linux

How to find,copy and rename files in linux?

I am trying to find all files in a directory and sub-directories and then copy them to a different directory. However some of them have the same name, so I need to copy the files over and then if there are two files have the same name, rename one of those files. So far I have managed to copy all found files with a unique name over using:

#!/bin/bash if [ ! -e $2 ] ; then mkdir $2 echo "Directory created" fi if [ ! -e $1 ] ; then echo "image source does not exists" fi find $1 -name IMG_****.JPG -exec cp <> $2 \; 

However, I now need some sort of if statement to figure out if a file has the same name as another file that has been copied.

One * matches all, you don’t need four of them. If you want to match exactly four characters, you can do . where each ? matches only one character. Also, you need to quote «IMG_. JPG» (like I did) to prevent shell from expanding it. You probably got lucky and there is no IMG_. JPG in the directory you are calling find from, so the pattern is kept intact.

Sure! I recommend reading this page: mywiki.wooledge.org/BashPitfalls it has good information where beginners (myself included) usually get wrong with bash.

4 Answers 4

Since you are on linux, you are probably using cp from coreutils. If that is the case, let it do the backup for you by using cp —backup=t

Try this approach: put the list of files in a variable and copy each file looking if the copy operation succeeds. If not, try a different name.

FILES=`find $1 -name IMG_****.JPG | xargs -r` for FILE in $FILES; do cp -n $FILE destination # Check return error of latest command (i.e. cp) # through the $? variable and, in case # choose a different name for the destination done 

Inside the for statement, you can also put some incremental integer to try different names incrementally (e.g., name_1, name_2 and so on, until the cp command succeeds).

You are right, -n is —no-clobber . I confused it with the flag from other commands. The answer is fine now.

Sorry, I should have mentioned in the question that I am only learning linux for the first time, so could you explain what the parts of your code do please? sorry.

for file in $1/**/IMG_*.jpg ; do target=$2/$(basename "$file") SUFF=0 while [[ -f "$target$SUFF" ]] ; do (( SUFF++ )) done cp "$file" "$target$SUFF" done 

in your script in place of the find command to append integer suffixes to identically-named files

You can use rsync with the following switches for more control

rsync —backup —backup-dir=DIR —suffix=SUFFIX -az

-b, —backup

With this option, preexisting destination files are renamed as each file is transferred or deleted. You can control where the backup file goes and what (if any) suffix gets appended using the —backup-dir and —suffix options.

—backup-dir=DIR

In combination with the —backup option, this tells rsync to store all backups in the specified directory on the receiving side. This can be used for incremental backups. You can additionally specify a backup suffix using the —suffix option (otherwise the files backed up in the specified directory will keep their original filenames).

—suffix=SUFFIX

This option allows you to override the default backup suffix used with the —backup (-b) option. The default suffix is a ~ if no —backup-dir was specified, otherwise it is an empty string.

You can use rsycn to either sync two folders on local file system or on a remote file system. You can even do syncing over ssh connection.

Читайте также:  Linux time время выполнения

rsync is amazingly powerful. See the man page for all the options.

Источник

How copy and rename files found in «find» function Linux?

I have a folder named /home/user/temps which has 487 folders. In each folder I have a file called thumb.png. I want to copy all files named thumb.png to a separate folder and rename them based on the folder they came from.

rename them, how? If you replace the directory delimiter with something — let’s say underline (_), you may get collisions with files, which already contain an underline. That’s true for every valid character, and beside / and \0, which are forbidden in filenames, there is no safe harbor — any character might produce a collision.

6 Answers 6

for file in /home/user/temps/*/thumb.png; do new_file=$; cp "$file" "$"; done; 

the canonical wisdom, by the way, is that using find for this is a bad idea — simply using shell expansion is much more reliable. Also, this assumes bash , but I figure that’s a safe assumption 🙂

for clarity, I’ll break it down:

# shell-expansion to loop specified files for file in /home/user/temps/*/thumb.png; do # replace 'temps' with 'new_folder' in the path # '/home/temps/abc/thumb.png' becomes '/home/new_folder/abc/thumb.png' new_file=$; # drop '/thumb' from the path # '/home/new_folder/abc/thumb.png' becomes '/home/new_folder/abc.png' cp "$file" "$"; done; 

details on the $ construct can be found here.

the quotes in the cp line are important to handle spaces and newlines etc. in filenames.

@user: $ produces the value of VARIABLE but with the pattern replaces by the replacement text. Here the pattern is /thumb (the / needs to be escaped so that it doesn’t look like $ , which makes it a global replacement instead of a first-occurrence replacement) and the replacement text is empty.

You’re assuming that the 487 directories are directly under /home/user/temps , which is not clear from the question. If they aren’t, you need find or ** .

This solution «flattens» the files in sub- and subsubdirectories so they all sit in one big directory. The new file name reflects the original path. For example temps/dir/subdir/thumb.png will become newdir/temps_dir_subdir_thumb.png .

find temps/ -name "thumb.png" | while IFS= read -r f do cp -v "$f" "newdir/$" done 

can also be done in one line

find temps/ -name "thumb.png" | while IFS= read -r f; do cp -v "$f" "newdir/$"; done 
$ find temps/ -name "thumb.png" | while IFS= read -r f; do cp -v "$f" "newdir/$"; done `temps/thumb.png' -> `newdir/temps_thumb.png' `temps/dir3/thumb.png' -> `newdir/temps_dir3_thumb.png' `temps/dir3/dir31/thumb.png' -> `newdir/temps_dir3_dir31_thumb.png' `temps/dir3/dir32/thumb.png' -> `newdir/temps_dir3_dir32_thumb.png' `temps/dir1/thumb.png' -> `newdir/temps_dir1_thumb.png' `temps/dir2/thumb.png' -> `newdir/temps_dir2_thumb.png' `temps/dir2/dir21/thumb.png' -> `newdir/temps_dir2_dir21_thumb.png' 

You must execute the command from the parent directory of temps . Also newdir must exists and must be a sibling directory of temps . These can deviate but then you must be really carefull how to write the command.

Читайте также:  Horizon agent for linux

If you are unsure then prepend cp with echo to see what is going to be executed.

find temps/ -name "thumb.png" | while IFS= read -r f; do echo cp -v "$f" "newdir/$"; done 

If you are really sure and don’t the need the one line per copy anymore then drop the -v from cp .

This works using parameter expansion: $ . It takes the content of the variable f (which contains the filename with path) and replaces every occurence of / with _ .

Note that this is a dumb text search and replace. In some rare cases two distinct file might end up to the same name. If that happens one of the files will overwrite the other.

For example two files temps/dir/thumb.png and temps/dir_thumb.png . Both files will be renamed to temps_dir_thumb.png . So one file will be lost. Which file will be lost is dependent on the order of how find found them on disk.

Also note: obligatory pedantic warning: if your filenames contain newlines this command will break horribly.

Источник

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' 

Источник

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 -iname ‘*.mp3’ -mtime -1 -exec cp <> /home/my_path/ \; is there anything wrong with this command ? it’s not working

In Ubuntu 18 the curly braces also have to be put into single quotes: find -iname ‘*.mp3’ -mtime -1 -exec cp ‘<>‘ /home/my_path/ \;

i faced an issue something like this.

Actually, in two ways you can process find command output in copy command

  1. If find command’s output doesn’t contain any space i.e if file name doesn’t contain space in it then you can use below mentioned command: Syntax: find | xargs cp -t Example: find -mtime -1 -type f | xargs cp -t inner/
  2. But most of the time our production data files might contain space in it. So most of time below mentioned command is safer: Syntax: find -exec cp ‘<>‘ \; Example find -mtime -1 -type f -exec cp ‘<>‘ inner/ \;
Читайте также:  Как отключить порт linux

In the second example, last part i.e semi-colon is also considered as part of find command, that should be escaped before press the enter button. Otherwise you will get an error something like this

find: missing argument to `-exec' 

In your case, copy command syntax is wrong in order to copy find file into /home/shantanu/tosend . The following command will work:

find /home/shantanu/processed/ -name '*2011*.xml' -exec cp <> /home/shantanu/tosend \; 

Источник

Linux ‘find’ command: How to find and copy files

Linux find/copy FAQ: How can I use the find command to find many files and copy them all to a directory?

I ran into a situation this morning where I needed to use the Linux find command to (a) find all the MP3 files beneath my current directory and (b) copy them to another directory. In this case I didn’t want to do a cp -r command or tar command to preserve the directory structure; instead, I wanted all of the files to end up in the same directory (so I could easily import them into iTunes).

In short, here’s the find command I used to find and copy all of those files:

find . -type f -name "*.mp3" -exec cp <> /tmp/MusicFiles \;

If you’re familiar with the find command and have used the -exec option before, the only thing hard about this command is knowing where to put the curly braces and the \; in the command.

  1. In this example, all the MP3 files beneath the current directory are copied into the target directory (/tmp/MusicFiles). Again, this isn’t a cp -r command; all of these files will end up in one folder.
  2. As a result, if there are duplicate file names, some of the files will be lost.
  3. If you don’t want to overwrite existing files, use the cp -n command, like this:
find . -type f -name "*.mp3" -exec cp -n <> /tmp/MusicFiles \;

The -n option of the cp command means “no clobber,” and you can also type that as cp —no-clobber on some systems, such as Linux. (The -n option appears to work on MacOS systems, but —no-clobber does not.) Be sure to test this command before using it on something important; I haven’t tested it yet, I just read the man page for the cp command.)

If you ever need to use the Linux find command to find a large collection of files and copy them to another location, I hope this has been helpful.

Another example: Find and move

Here’s another example of a “find and copy” command I just used, though in this case it was a “find and move” command. In this case I had a bunch of files (with unique names) in subdirectories, and used this command to copy them all to the current directory:

As before, this is a dangerous command, so be careful. With this command, if you have duplicate filenames, you will definitely lose data during the move operations.

Источник

Оцените статью
Adblock
detector