LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   How to copy a file to all subfolders in a directory using a single command? (https://www.linuxquestions.org/questions/linux-newbie-8/how-to-copy-a-file-to-all-subfolders-in-a-directory-using-a-single-command-820478/)

SirTristan 07-18-2010 04:05 AM

How to copy a file to all subfolders in a directory using a single command?
 
I'd like to copy a file, say widgets/water.txt, to all subfolders in the folder widgets using a single command. So if the folder widgets has 10 subfolders like widgets/blue, widgets/green, etc. I'd like to copy water.txt to all of them with one command.

I tried the commands
Code:

cp water.txt ./*/water.txt
cp water.txt ./*/

However these don't seem to work. The latter gives 'cp: omitting directory' errors. What is the right way to do this?

zirias 07-18-2010 04:27 AM

depends on what you mean by "with a single command". It is possible with a single commandline, using the for command (in most shells a builtin):
Code:

for d in */; do cp water.txt "$d"; done
PS: the reason your command doesn't work is that '*/' is expanded by the shell before invoking cp, and cp interprets only the LAST argument (in that case the last subdir found by your shell) as the target to copy to, so that's the reason for the "directory omitted" message, it refuses to copy directories without the -r switch.

The "for" command does the right thing by invoking cp individually for each target directory.

unSpawn 07-18-2010 06:55 AM

Something like 'find ${PWD}/* -type d -print0 | xargs -0 -iD cp /path/to/water.txt 'D';'?

MTK358 07-18-2010 07:35 AM

Quote:

Originally Posted by SirTristan (Post 4036921)
I'd like to copy a file, say widgets/water.txt, to all subfolders in the folder widgets using a single command. So if the folder widgets has 10 subfolders like widgets/blue, widgets/green, etc. I'd like to copy water.txt to all of them with one command.

I tried the commands
Code:

cp water.txt ./*/water.txt
cp water.txt ./*/

However these don't seem to work. The latter gives 'cp: omitting directory' errors. What is the right way to do this?

It's not possible with a single command. The cp command copies all but the last in the list of files to the last item, which specifies the directory. And remember that the shell, not cp, expands the wildcards based on existing files.

Code:

for i in * # iterate over all files in current dir
do
        if [ -d "$i" ] # if it's a directory
        then
                cp water.txt "$i" # copy water.txt into it
        fi
done

The find command won't work because it searches in subdirectories.

unSpawn 07-18-2010 07:52 AM

Quote:

Originally Posted by MTK358 (Post 4037052)
The find command won't work because it searches in subdirectories.

As long as the OP is in the /path/to/widgets/ directory it'll work. If it doesn't then do show it doesn't by posting output.

MTK358 07-18-2010 08:24 AM

But i don't think the OP wants water.txt in all the subdirectories and their subderectories, too.

zirias 07-18-2010 08:58 AM

What's this silly argument good for? I don't think the OP wanted to copy it recursively into a directory tree, so i didn't use find -- finding all directories in the current directory is done fine by the shell using the pattern '*/'.

But, in case you actually WANT all subdirectories recursively, find is the way to go, as posted by unSpawn.

Matching all files with '*' and later checking wheter it is a directory doesn't make sense.

And, as I already explained, it's not possible using a single command, there are always at least two commands involved, BUT it is very well possible using a single line.

SirTristan 07-18-2010 11:19 PM

Thanks guys :)

Yes zirias is right, I didn't want to copy to the whole directory tree, just the direct subfolders. zirias' code works great:
Code:

for d in */; do cp wp-salesengine-page.php "$d"; done


All times are GMT -5. The time now is 08:10 AM.