2

I've little inconvenience while copying image files from another Android Project to my current one.

Suppose I've files called nice_little_icon.png in each of the directories drawable-ldpi, drawable-mdpi, drawable-hdpi, drawable-xhdpi and drawable-xxhdpi, which are under res directory of Project1.

Now how do I copy these files into project2's res directory using single Linux/Unix command?

so my end result will look like

Project1/../res/drawable-ldpi/nice_little_icon.png -> Project2/../res/drawable-ldpi/nice_little_icon.png
Project1/../res/drawable-mdpi/nice_little_icon.png -> Project2/../res/drawable-mdpi/nice_little_icon.png
Project1/../res/drawable-hdpi/nice_little_icon.png -> Project2/../res/drawable-mdpi/nice_little_icon.png
Project1/../res/drawable-xhdpi/nice_little_icon.png -> Project2/../res/drawable-xhdpi/nice_little_icon.png
Project1/../res/drawable-xxhdpi/nice_little_icon.png -> Project2/../res/drawable-xxhdpi/nice_little_icon.png
ilkkachu
  • 138,973

2 Answers2

2

You can use rsync.

rsync -avzh -n --include='*/' --include='*nice_little_icon.png' --exclude='*' Project1/../res/ Project2/../res/

This will only copy the files called nice_little_icon.png from Project1/../res/* to Project2/../res/, and will create the file's parent directories (drawable-ldpi, drawable-ldpi, etc.) under Project2/../res/ if they don't exist.

Explaining the rsync command:

  • -avzh : -a basically means 'recursive, and preserve the timestamp, permissions, and a few other things', -v means verbose, -z means compress files while transferring (not really needed but I like to use it anyways), and -h means print in human readable.
  • -n : means dry-run. So running this command won't do anything. You'll need to remove this to actually make the command take action.
  • --include='*/' --include='*nice_little_icon.png' --exclude='*' : this is basically the way to tell rsync to only copy the files ending in nice_little_icon.png and exclude everything else.
  • Project1/../res/ : the source directory. The last / is very important, it means 'copy whatever is under res/'. If you removed that /, it will copy the actual directory res to the destination, which is not what you want.
  • Project2/../res/ : the destination directory.

When you run the above command, it will show you what it's going to do (i.e. what directories and files it will copy):

./
drawable-hdpi/
drawable-hdpi/nice_little_icon.png
drawable-mdpi/
drawable-mdpi/nice_little_icon.png
...

It should look something like that (i.e. the parent directories, and only the file nice_little_icon.png). If it looks okay, remove the -n from the command to actually make it take action and copy the files.

Alaa Ali
  • 1,875
  • Woovvvv... Cool answer.. Thanks for the amazing help... Although once little concern. Wouldn't this use the network to copy the file (I mean over ssh)? So wouldn't it make little expensive operation for a simple file copy? – Samuel Robert Aug 07 '16 at 16:23
  • Our source directory is Project1/../res/ and destination directory is Project2/../res/. This tells rsync that the copy is local, so it won't do it over the network. rsync is a copying tool. It was probably initially developed and optimized to do copies over the network (and maybe you've always seen it used for remote copying), but it can be used for local copying just fine, like we're using it here. If our destination was something like this: 10.0.1.2:Project2/../res/, then yes, that tells rsync to copy those files to this server over SSH, but that's not what we're doing here =). – Alaa Ali Aug 07 '16 at 17:27
  • Ya you're right... I checked the man page of the rsync command. Nicely documented there as you said. Thanks – Samuel Robert Aug 08 '16 at 09:23
1

You can use the pax command (a standardized replacement for tar and cpio). This command is present on all POSIX-compliant systems, but beware that some Linux distributions omit it from their default installation. pax copies each path under the destination directory.

pax -rw -pe drawable-*/nice_little_icon.png ../../Project2/res/

Instead of relying on wildcards in the shell, you can use the -s option to ignore some files.

pax -rw -pe -'s!^drawable-[^/]*/nice_little_icon\.png$!&!' -'s!.*/.*!!' drawable-* ../../Project2/res/