Linux/Cygwin递归复制文件更改扩展名

Linux/Cygwin递归复制文件更改扩展名,linux,find,rsync,xargs,cp,Linux,Find,Rsync,Xargs,Cp,我正在寻找一种方法,以递归方式查找扩展名为X(.js)的文件,并在扩展名为Y(.ts)的同一目录中复制该文件 e、 g./foo/bar/foobar.js-->/foo/bar/foobar.js和/foo/bar/foobar.ts /foo/bar.js-->/foo/bar.js和/foo/bar.ts等 我的尽职调查: 我曾考虑使用find&xargs&cp和大括号扩展(cpfoobar.{js,ts}),但xargs使用大括号表示从xargs传递的文件列表。这让我很难过,因为我最近发

我正在寻找一种方法,以递归方式查找扩展名为X(.js)的文件,并在扩展名为Y(.ts)的同一目录中复制该文件

e、 g./foo/bar/foobar.js-->/foo/bar/foobar.js和/foo/bar/foobar.ts

/foo/bar.js-->/foo/bar.js和/foo/bar.ts等

我的尽职调查: 我曾考虑使用find&xargs&cp和大括号扩展(
cpfoobar.{js,ts}
),但xargs使用大括号表示从xargs传递的文件列表。这让我很难过,因为我最近发现了一种很棒的调味汁,它是支架扩展/替换

我觉得必须有一个单线解决方案,但我正在努力想出一个

我找到了执行该任务的方法:将所需的文件复制到一个新目录,然后将该目录与新目录合并;在每个目录中递归运行重命名脚本;使用rsync进行复制;使用find、xargs和cpio

目前看来,像这样运行重命名脚本是我最终要做的事情

find . -name "*.js" -exec bash -c 'name="{}"; cp "$name" "${name%.js}.ts"' \;
使用,您可以通过使用
-exec
选项直接在找到的文件上执行命令;您不需要通过xargs进行管道传输。它采用命令名,后跟命令的参数,后跟单个参数
,必须对其进行转义以避免shell对其进行解释
find
将用找到的文件替换命令名或参数中出现的任何
{}


为了调用具有适当结尾的命令,可以采取多种方法,但一种简单的方法是使用Bash。您需要定义一个包含名称的shell参数(在本例中,我创造性地选择了
name={}
),然后可以对其使用参数扩展
${variable%suffix}
$variable
的值中去掉
后缀
;然后我将
.ts
添加到末尾,并使用我要查找的名称。

最好询问
xargs
不专门解释
{}
。但是,您想如何从xargs中的
foobar.js
获取
foobar
?我在xargs中使用了{}作为参数列表。我想我认为那是做这件事的方法。哎呀。无论如何,如果有一种方法可以在传递给xargs的参数列表上执行sed/awk/bash魔术,以获得所需的名称更改,我会很高兴。我想@choroba也不知道怎么做?谢谢。在看到一些帖子中使用了on-exec之后,我刚刚阅读了它。有人能解释一下尾随\;我理解命令的其余部分,但我对尾部斜杠的效果很好奇。@NKlosterman没问题!我已经用引号更新了我的答案,如果你的文件名称中有空格,并且提供了一些链接,那么会更安全一些。尾随的
\
是在
-exec
的参数停止时告诉
find
。它正在寻找一个由
组成的参数
,但默认情况下,shell会将其解释为
find
命令末尾的分隔符,因此您需要引用它。你也可以写
;',但这比
\”多个字符…我想你的意思是“-exec允许你直接在使用find找到的文件上执行命令…”@NKlosterman啊,我的措辞有点含糊不清。我的意思是“在使用
-exec
找到的文件上执行命令”,而不是“在使用
-exec
]找到的文件上执行命令”。我将重新措辞以使其更清楚。