在 macOS 上,我的文件夹结构如下
├── src
└── components
└── componentA
└── README.md
└── componentB
└── README.md
└── destination
└── components
├── componentA
└── componentB
README.md
我想知道在单个命令下将所有内容复制src
到destination
、基于源的映射的方法是什么
答案1
在中使用循环bash
:
shopt -s nullglob dotglob globstar
for srcfile in src/**/README.md; do
destfile=destination/${srcfile#src/}
mkdir -p "${destfile%/*}" &&
cp "$srcfile" "$destfile"
done
在这里,我们使用**
glob(通过globstar
在 中设置 shell 选项来启用bash
)来循环遍历目录README.md
下任何位置的所有文件src
。
对于每个文件,通过将初始src/
字符串替换为destination/
.来计算目标路径名。然后创建目标目录并复制文件。
shellnullglob
选项确保如果模式与任何名称不匹配,循环根本不会运行,并且 thodotglob
选项启用隐藏名称的匹配。
您想要复制所有*.md
文件吗?请在模式中使用*.md
来代替。README.md
您可以使用任何 shell 将整个过程作为单个命令运行
bash -O globstar -O nullglob -O dotglob -c 'for s in src/**/README.md; do d=destination/${s#src/}; mkdir -p "${d%/*}" && cp "$s" "$d"; done'
使用find
, 进行额外检查以确保README.md
找到的文件是常规文件:
find src -type f -name README.md -exec sh -c '
for srcfile do
destfile=destination/${srcfile#src/}
mkdir -p "${destfile%/*}" &&
cp "$srcfile" "$destfile"
done' sh {} +
sh -c
内联脚本中的循环体是,这应该不足为奇完全相同的bash
到顶部脚本中的循环。
答案2
和GNU cp
:
cd src
cp --parents -t ../destination components/*/README.md
请注意,cp
OSX 版本没有--parents
此选项。
rsync
那么你可以使用:
rsync -av --include '*/' --include='*/README.md' --exclude='*' src/ destination
答案3
最初认为如果有一个命令可以注册为 npm 脚本就好了,但最终我想出了一个解决方案,如下所示。
components=(src/components/*)
for dir in "${components[@]}";
do
files=($dir/*.md)
folder_name=${dir##*/}
for file in "${files[@]}";
do
mkdir -p "destination/$folder_name/";
cp "$file" "destination/$folder_name/";
done
done
答案4
对于给定的文件夹结构...只需这个命令行就可以工作
cd src; for i in `find . -name README.md`; do cp $i ../destination/$i; done; cd ..
希望能帮助到你