三点通配符

三点通配符

我有一个非常大的源代码目录结构,很难使用。我想运行一个工具将其转换为更适合我的 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/

相关内容