I'm not really sure how to phrase this, and maybe that's why I can't find anything, but I want to reuse the values enumerated by a wildcard in a command. Is this possible?
Scenario:
$ ls /dir
1 2 3
Contents of /dir are directories 1, 2, and 3.
$ cp /dir/*/file .
Results in file being copied from /dir/1 /dir/2 and /dir/3 to here.
What I would like to do is copy the files to a new destination name based on the wildcard expansion.
$ cp /dir/*/file ???-file
would result in /dir/*/file being copied to 1-file, 2-file, and 3-file. What I can't figured out is the ???
portion to tell Bash I want to use the wildcard-expanded values.
Using the wildcard in the target nets a cp
error:
cp: target `*-file' is not a directory.
Is there something else in Bash that can be used here?
The find
command has {}
to use with -exec
which is similar to what I am looking for above.
My first thought is you are probably making this problem too complicated. However, it is solvable.
You can do something like this with a crazy bash loop:
that uses a couple of bash string operators to extract the number of the source directory.
I guarantee there are waaay better ways to do this, that's just what came to mind.
zmv is a shell function, often used via
alias mmv='noglob zmv -W'
for an even easier invocation, but in this case you want the regular usage, plus -C to copy instead of move.As Phil has said, you'll need to iterate over the elements of the expanded wildcard; extracting the bit you care about (in your example, the name of the directory under dir/) and then acting on that extracted value.
I've got a different quick and hacky way to do this below. The obvious bug is that this is going to break if there are spaces in filenames, but this is not the only bug.
On most distros (using util-linux's rename):
On Debian and Ubuntu (blame Debian):
Or using Perl's rename (on Debian and Ubuntu, I don't know where to find it in other distros):
It's not pretty:
If I got your point, mcp is doing what you want to.
Hint: mcp belongs to the mmv package.
Your situation:
The solution:
I think it should be mostly self-explanatory
What happens here is that mcp takes a from and a to argument. The from argument can contain shell wildcard patterns (*,?) that match a set of files. These matches are backreferenced in the to pattern in an ordered way as #1, #2, #3 and so forth.