0

I have some files in a recursive folder structure, which I would like to copy to destination and give them a uuid name instead of the original name (because the names collide).

Nonrmally I would do something like this:

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 \;

but because the names collide, I am unable to do this. Thus, I would like to assign a uuid name to each file which is being copied. To this end, I have tried this:

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" \;

but I get only copied file :( rather than a bunch of files in the folders.

AJW
  • 103
  • What do you mean that you only get a copied file rather than a bunch of files in the folders? That isn't clear. – Nasir Riley Sep 10 '21 at 13:33

1 Answers1

2

The reason you're only getting one file is because when the shell parses your find command, it expands $(uuidgen) to the result of running uuidgen and then passes that as a static string to find. You also have some other, minor issues:

  • avoid using CAPS for variable names since that is by convention used for global environment variables and variable name collisions can be hard to debug.
  • Your find is needlessly complicated.
  • Always quote your variables!
  • No need for \ after &&, the && is enough, but it is also not needed for the variable declarations. Here's a working version of your script with some improvements:
#!/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 {} ;

The trick is to call an sh script from within find. This takes care of the rest. We need to pass it sh (or any other random string, it just needs a 1st and 2nd argument) and {} because the first argument becomes $0 in this context, so we need a second to get $1.

terdon
  • 242,166
  • thank you! you saved my day today! I will try and adhere to the principles you have stated – AJW Sep 10 '21 at 16:34