问题
I'm looking for a way to recursively find files with extension X (.js) and make a copy of the file in the same directory with extension Y (.ts).
e.g. /foo/bar/foobar.js --> /foo/bar/foobar.js and /foo/bar/foobar.ts
/foo/bar.js --> /foo/bar.js and /foo/bar.ts etc etc
My due diligence:
I was thinking of using find & xargs & cp and brace expansion (cp foobar.{js,ts}
) but xargs uses the braces to denote the list of files passed from xargs. This makes me sad as I just recently discovered the awesome-sauce that is brace expansion/substitution.
I feel like there has to be a one-line solution but I'm struggling to come up with one.
I've found ideas for performing the task: copying the desired to a new directory and then merging this directory with the new one; recursively run a renaming script in each directory; copy using rsync; use find, xargs and cpio.
As it stands it appears that running a renaming script script like this is what I'll end up doing.
回答1:
find . -name "*.js" -exec bash -c 'name="{}"; cp "$name" "${name%.js}.ts"' \;
Using find, you can execute a command directly on a file that you've found, by using the -exec
option; you don't need to pipe it through xargs. It takes the command name followed by arguments to the command, followed by a single argument ;
, which you have to escape to avoid the shell interpreting it. find
will replace any occurrence of {}
in the command name or arguments with the file found.
In order call a command with the appropriate ending substituted, there are multiple approaches you can take, but a simple one is to use Bash's parameter expansion. You need to define a shell parameter that contains the name (in this case, I creatively chose name={}
), and then you can use parameter expansion on it. ${variable%suffix}
strips off suffix
from the value of $variable
; I then add on .ts
to the end, and have the name I'm looking for.
来源:https://stackoverflow.com/questions/12923341/linux-cygwin-recursively-copy-file-change-extension