Travis
Travis

Reputation: 705

How can I use terminal to copy and rename files from multiple folders?

I have a folder called "week1", and in that folder there are about ten other folders that all contain multiple files, including one called "submit.pdf". I would like to be able to copy all of the "submit.pdf" files into one folder, ideally using Terminal to expedite the process. I've tried cp week1/*/submit.pdf week1/ as well as cp week1/*/*.pdf week1/, but it had only been ending up copying one file. I just realized that it has been writing over each file every time which is why I'm stuck with one...is there anyway I can prevent that from happening?

Upvotes: 2

Views: 8313

Answers (2)

BRPocock
BRPocock

Reputation: 13914

You don't indicate your OS, but if you're using Gnu cp, you can use cp week1/*/submit.pdf --backup=t week/ to have it (arbitrarily) number files that already exist; but, that won't give you any real way to identify which-is-which.

You could, perhaps, do something like this:

 for file in week1/*/submit.pdf; do cp "$file" "${file//\//-}"; done

… which will produce files named something like "week1-subdir-submit.pdf"

For what it's worth, the "${var/s/r}" notation means to take var, but before inserting its value, search for s (\/, meaning /, escaped because of the other special / in that expression), and replace it with r (-), to make the unique filenames.

Edit: There's actually one more / in there, to make it match multiple times, making the syntax:

             "${ var           /        /                 \/  /      -    }"
                 take "var"    replace  every instance of /   with   -

Upvotes: 3

csl
csl

Reputation: 11358

find to the rescue! Rule of thumb: If you can list the files you want with find, you can copy them. So try first this:

$ cd your_folder
$ find . -type f -iname 'submit.pdf'

Some notes:

  • find . means "start finding from the current directory"
  • -type -f means "only find regular files" (i.e., not directories)
  • -iname 'submit.pdf' "... with case-insensitive name 'submit.dpf'". You don't need to use 'quotation', but if you want to search using wildcards, you need to. E.g.:

     ~ foo$ find /usr/lib -iname '*.So*'
     /usr/lib/pam/pam_deny.so.2
     /usr/lib/pam/pam_env.so.2
     /usr/lib/pam/pam_group.so.2
     ...
    

If you want to search case-sensitive, just use -name instead of -iname.

When this works, you can copy each file by using the -exec command. exec works by letting you specify a command to use on hits. It will run the command for each file find finds, and put the name of the file in {}. You end the sequence of commands by specifying \;.

So to echo all the files, do this:

$ find . -type f -iname submit.pdf -exec echo Found file {} \;

To copy them one by one:

$ find . -type f -iname submit.pdf -exec cp {} /destination/folder \;

Hope this helps!

Upvotes: 1

Related Questions