我在递归文件夹结构中有一些文件,我想将其复制到目标并为它们指定一个 uuid 名称而不是原始名称(因为名称冲突)。
非正常情况下我会做这样的事情:
SOURCE_DIR="/some/*/dir/struct/*/img_files" &&\
DEST_DIR="/dest/folder/0" &&\
rm -rf $DEST_DIR &&\
mkdir -p $DEST_DIR &&\
find $SOURCE_DIR \( -name "*.jpg" \) -exec cp {} $DEST_DIR \;
但由于名称冲突,我无法做到这一点。因此,我想为每个正在复制的文件分配一个 uuid 名称。为此,我做了这样的尝试:
SOURCE_DIR="/some/*/dir/struct/*/img_files" &&\
DEST_DIR="/dest/folder/0" &&\
rm -rf $DEST_DIR &&\
mkdir -p $DEST_DIR &&\
find $SOURCE_DIR \( -name "*.jpg" \) -exec cp {} $DEST_DIR/"$(uuidgen).jpg" \;
但我只得到复制的文件:(而不是文件夹中的一堆文件。
答案1
您只获得一个文件的原因是,当 shell 解析您的find
命令时,它会扩展$(uuidgen)
为运行结果uuidgen
,然后传递该结果作为静态字符串到find
。您还有其他一些小问题:
- 避免对变量名使用大写字母,因为这是全局环境变量的惯例,并且变量名冲突可能很难调试。
- 你的
find
事情不必要地复杂。 - 始终引用您的变量!
- 不需要
\
after&&
,就&&
足够了,但变量声明也不需要。这是您的脚本的工作版本,并进行了一些改进:
#!/bin/bash
source_dir="/some/*/dir/struct/*/img_files"
dest_dir="/dest/folder/0"
source_dir="."
dest_dir="bar"
rm -rf "$dest_dir" &&
mkdir -p "$dest_dir" &&
find "$source_dir" -name "*.jpg" -exec sh -c 'name='$dest_dir'/$(uuidgen).jpg; cp "$1" "$name"' sh {} \;
诀窍是sh
从内部调用脚本find
。这会处理其余的事情。我们需要传递它sh
(或任何其他随机字符串,它只需要第一个和第二个参数),并且{}
因为第一个参数$0
在这个上下文中,所以我们需要第二个参数来获取$1
。