Xian Qi
Xian Qi

Reputation: 1

Copying files with wildcard * why isn't it working?

There are 3 txt files called

1.txt 2.txt 3.txt

I want to batch copy with the name

1.txt.cp 2.txt.cp 3.txt.cp

using the wildcard *.

I entered the command cp *.txt *.txt.cp but it isn't working.

cp : target *.txt.cp : is not a directory

What is the problem?

Upvotes: 0

Views: 3246

Answers (3)

David C. Rankin
David C. Rankin

Reputation: 84579

About the easiest and robust way to do what you are attempting is to collect the files with find . -type f -name "*.txt" which will find all files ending in ".txt" below the current directory. To limit to just the current directory add -maxdepth 1 before -type .... To ensure filenames with spaces or other strange characters are correctly handled add the -print0 option to ensure the filenames are nul-termianted. Putting that altogether, you could collect the files with:

find . -maxdepth 1 -type f -name "*.txt" -print0

Now to process the files, copying them to add a .cp ending (extension) to the filename, you can use GNU xargs using the -0 option to handle the nul-terminated filenames and the -I '{}' replace-str option to process each filename which will replace '{}' in the xargs command. Putting that together, you would have:

xargs -0 -I '{}' cp -a '{}' '{}.cp'

Above you simply copy (cp -a) preserving attributes '{}' to '{}.cp' adding the .cp extension.

Putting it altogether, you would simply pipe the find output to xargs, e.g.:

find . -maxdepth 1 -type f -name "*.txt" -print0 | xargs -0 -I '{}' cp -a '{}' '{}.cp'

If you want a full quick example, just create the files and then prove to yourself it works as intended, e.g.

$ touch {1..3}.txt
$ find . -maxdepth 1 -type f -name "*.txt" -print0 | xargs -0 -I '{}' cp -a '{}' '{}.cp'

Resulting files in the current directory:

$ ls -al [1-3]*
-rw-r--r-- 1 david david 0 Aug 24 19:07 1.txt
-rw-r--r-- 1 david david 0 Aug 24 19:07 1.txt.cp
-rw-r--r-- 1 david david 0 Aug 24 19:07 2.txt
-rw-r--r-- 1 david david 0 Aug 24 19:07 2.txt.cp
-rw-r--r-- 1 david david 0 Aug 24 19:07 3.txt
-rw-r--r-- 1 david david 0 Aug 24 19:07 3.txt.cp

Let me know if you have questions. There are many additional ways to tailor the find command to match just what you want to find using regular expressions instead of simple file-globbing if needed.

Upvotes: 0

Serge Ballesta
Serge Ballesta

Reputation: 149085

If you are used to MS/Windown CMD shell, it is important to note that Unix system handle very differently the wild cards. MS/Windows has kept the MS/DOS rule that said that wild cards were not interpreted but were passed to the command. The command sees the wildcard characters and can handle the second * in the command as noting where the match from the first should go, making copy ab.* cd.* sensible.

In Unix (and derivatives like Linux) the shell is in charge of handling the wildcards and it replaces any word containing one with all the possible matches. The good news is that the command has not to care about that. But the downside is that if the current folder contains ab.txt ab.md5 cd.jpg, a command copy ab.* cd.* will be translated into copy ab.txt ab.md5 cd.jpg which is probably not want you would expect...

The underlying reason is Unix shells are much more versatile than the good old MS/DOS inherited CMD.EXE and do have simple to use for and if compound commands. Just look at @Halley Oliveira's answer for the syntax for your use case.

Upvotes: 1

Halley Oliveira
Halley Oliveira

Reputation: 389

Use: for i in *.txt; do cp "$i" "$i.cp"; done

Example:

$ ls -l *.txt
-rw-r--r-- 1 halley halley 20 out 27 08:14 1.txt
-rw-r--r-- 1 halley halley 25 out 27 08:14 2.txt
-rw-r--r-- 1 halley halley 33 out 27 08:15 3.txt
$ ls -l *.cp
ls: could not access '*.cp': File or directory does not exist
$ for i in *.txt; do cp "$i" "$i.cp"; done
$ ls -l *.cp
-rw-r--r-- 1 halley halley 20 out 27 08:32 1.txt.cp
-rw-r--r-- 1 halley halley 25 out 27 08:32 2.txt.cp
-rw-r--r-- 1 halley halley 33 out 27 08:32 3.txt.cp
$ for i in *.txt; do diff "$i" "$i.cp"; done
$ 

Upvotes: 2

Related Questions