如何根据路径将多个文件复制到多个位置?

如何根据路径将多个文件复制到多个位置?

在 macOS 上,我的文件夹结构如下

├── src
    └── components
        └── componentA
            └── README.md
        └── componentB
            └── README.md
└── destination
    └── components
        ├── componentA
        └── componentB

README.md我想知道在单个命令下将所有内容复制srcdestination、基于源的映射的方法是什么

答案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

请注意,cpOSX 版本没有--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 ..

希望能帮助到你

相关内容