48

I would like to copy files with multiple extensions to a single destination directory.

For example, I can use the following command to copy all .txt files in the working directory to a directory called destination:

cp -v *.txt destination/

And I can use the following to copy all .png directories in the working directory to destination:

cp -v *.png destination/

But it's time consuming to type these as separate commands (even with the use of command history). So, is there any way that I can tell cp to copy files with either the pattern *.txt or the pattern *.png to destination? Ideally, I would like to be able to specify more than two patterns -- like instructing cp to copy all *.txt or *.png or *.jpg files to destination, for example.

I'm sure that all of this is possible using a shell script -- I'm using bash, for example -- but is there any way to accomplish it more simply, just from the console? Could I somehow use brace expansion to do it?

I know that it is possible to copy all files in the working directory except those matching certain specified patterns, but since my working directory contains far more file extensions that I don't want to copy than those I do, that would be a pain.

Do you have any thoughts on this?

1
  • 10
    cp -v *.txt *.png destination/?
    – iruvar
    Commented Sep 24, 2014 at 16:38

2 Answers 2

96

Brace expansion will get the job done. man bash and search for Brace Expansion.

cp *.{txt,jpg,png} destination/

EDIT:

In keeping with the OP's request, the command above was missing the verbose option:

cp -v *.{txt,jpg,png} destination/
4
  • 2
    Can I do this on Windows?
    – sergiol
    Commented Aug 18, 2016 at 17:45
  • 2
    If I do cp data/images/*.{jpg,jpeg,png,mp4} destination/ and an mp4 file does not exist, I get a No such file or directory error which breaks the script. Can I make the multiple extensions gracefully handle any missing formats?
    – BradGreens
    Commented Feb 25, 2019 at 17:22
  • 1
    @BradGreens You should really post a new question rather than asking here in the comments. Your question may even have an answer already. Posting a new question will not only get you an answer but it will then be searchable by others who need the same help. Commented Feb 25, 2019 at 21:05
  • 1
    @BradGreens Try redirecting standard error to the null device cp -v *.{txt,jpg,png} destination/ 2>/dev/null which doesn't affect standard output.
    – yoyoma2
    Commented Feb 4, 2022 at 1:49
0
for filename in /Photos/directory/* ; do
    filenameWithoutPath="${filename##*/}"
    first_num="${filenameWithoutPath%%.*}"
    last_num="${filenameWithoutPath##*.}"
    cp $filename /Photos/directory/$first_num-$last_num.jpg
done

Thats working!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .