Bash 复制特定类型的文件,但防止覆盖文件

Bash 复制特定类型的文件,但防止覆盖文件,bash,macos,sh,Bash,Macos,Sh,我需要将特定类型的所有文件复制到一个文件夹中,我的操作如下: find ./ -name '*.gql' -exec cp -prv '{}' '/path/to/dir/' ';' 但是,如果有两个文件具有相同的名称,尽管位于不同的子文件夹中,某些文件将被覆盖 是否可以保留所有复制的文件?可能重命名复制的文件,或者是否可以将文件夹结构保留在目标目录中?c.f.:cp实用程序的历史版本有一个-r选项…强烈建议不要使用它,因为它不能正确复制特殊文件、符号链接、,或者fifo。您可以使用-n防止覆

我需要将特定类型的所有文件复制到一个文件夹中,我的操作如下:

find ./ -name '*.gql' -exec cp -prv '{}' '/path/to/dir/' ';'
但是,如果有两个文件具有相同的名称,尽管位于不同的子文件夹中,某些文件将被覆盖

是否可以保留所有复制的文件?可能重命名复制的文件,或者是否可以将文件夹结构保留在目标目录中?

c.f.:
cp实用程序的历史版本有一个-r选项
强烈建议不要使用它,因为它不能正确复制特殊文件、符号链接、,或者fifo。
您可以使用
-n
防止覆盖,但更复杂的逻辑可能需要自定义代码

dest=/path/to/dir
while IFS= read -r -d '' filename # read null-delimited list from find 
do basename="${filename##*/}"
   if [[ -e "$dest/$basename" ]] 
   then ctr=0
        while [[ -e "$dest/$basename.$((++ctr))" ]]; do : ; done # find available name
        mv "$dest/$basename" "$dest/$basename.$ctr"
   fi
   cp -pv "$filename" "$dest/$basename"     
done < <( find ./ -name '*.gql' -type f -print0 ) # null-delimit
dest=/path/to/dir
当IFS=read-r-d“”文件名时#从find中读取空分隔列表
do basename=“${filename##*/}”
如果[-e“$dest/$basename”]]
那么ctr=0
而[[-e“$dest/$basename.$(++ctr))”];do:;完成#查找可用名称
mv“$dest/$basename”“$dest/$basename.$ctr”
fi
cp-pv“$filename”“$dest/$basename”

完成<如果您的
cp
支持备份,您可以查看
-b
/
--backup
(GNU
cp
支持备份)。@BenjaminW。我在一台mac电脑上,我使用的cp不支持它。如果您完全确定不会有具有“奇怪”名称的文件,您可以简化
查找
/
读取
,但这两种方式都可以。