我有一个非常大的源代码目录结构,很难使用。我想运行一个工具将其转换为更适合我的 Maven 结构。当我完成工作后,我再次运行该工具,将 Maven 结构转换回原来糟糕的结构。我非常熟悉各种 shell,是的,我可以编写一个包含数百个 cp 命令的脚本。但这将很难维持。
我希望能够使用 Perforce 的三点通配符之类的东西来移动或复制文件:
匹配当前工作目录及其所有子目录下的所有文件。 (匹配任何内容,包括斜杠,并且跨子目录执行此操作)
然后我的脚本将包含如下命令:
cp src/.../foobar/.../*.java trusted/src/main/java/.../foobar/.../*.java
这个想法是移动目录的子树,同时保持该子树的结构。
有任何想法吗?
我对 Gilles 的 rsync 解决方案有疑问。这是一个测试脚本:
#!/bin/bash
rm -rf source
mkdir -p source/server/src/com/bodhi/foobar/this
mkdir -p source/server/src/com/bodhi/foobar/that
mkdir -p source/server/src/com/bodhi/other
echo "Hello World" > source/server/src/com/bodhi/foobar/this/A.java
echo "Hello World" > source/server/src/com/bodhi/foobar/that/B.java
echo "Hello World" > source/server/src/com/bodhi/other/C.java
rm -rf target
mkdir -p target/foobar/src/main/java
rsync \
--include='**/foobar/**/*.java' \
--include='**/foobar/**/' \
--exclude='*' \
--prune-empty-dirs \
source/server/src/ target/foobar/src/main/java/
答案1
该通配符存在于 ksh93、bash ≥4.3(如果树中没有指向目录的符号链接则≥ 4.0)和 zsh 中。是拼写的**
。在 ksh93 中,需要首先使用 激活它set -o globstar
。在 bash 中,需要首先使用 激活它shopt -o globstar
。
ls -l src/**/foobar/**/*.java
但这并不能制作副本。的目标cp
是单个目录,cp
不进行任何通配符匹配。您不能使用单个cp
命令将文件拖放到不同的位置。
您可以使用同步反而。将源树的根和目标树的根传递给它,并定义包含和排除规则以仅复制所需的文件以及指向它们的目录。如果空目录与模式匹配,Rsync 也会复制它们,您可以使用 使其删除它们--prune-empty-dirs
。
rsync --include='**/foobar/**/*.java' --include='**/' \
--exclude='*' --prune-empty-dirs \
src/ trusted/src/main/java/
您可以使用的另一个工具是帕克斯。请注意,pax 是标准的,因为它是由 POSIX 定义的(与 rsync 不同),但某些 Linux 发行版在默认安装中省略了它(但它始终作为包提供)。做法与rsync类似:包含.java
文件,排除其余文件;语法有点奇怪:您指定一个模式替换,它可以是原始的以包含文件而不重命名它,也可以是空的替换以排除文件。根据需要在目标中自动创建前导目录。
pax -rw -s '/\.java$/&/' -s '/.*//' src/* trusted/src/main/java/