Skip to main content
Tweeted twitter.com/StackCodeReview/status/1470544159287255044
Became Hot Network Question
code-fence
Source Link
Toby Speight
  • 81.7k
  • 14
  • 101
  • 308
#!/bin/bash
# clone watchface changing names where required

# remember source and dest, trimming trailing / if needed
SOURCE=$(echo $1 | sed 's:/*$::')
DEST=$(echo $2 | sed 's:/*$::')

function showHelp {
    cat << EOF
./clone.sh source destination
Clone a existing "source" watchface to a new "destination" watchface.
The script copies and renames files that contain the "source" name and 
updates the watchface qml file to point to the renamed sources.

EOF
}

# the three-argument form is only intended to be used internally
if [ -f "$3" ] ; then
    if [[ "$3" == *.qml ]] ; then
        sed "s/$SOURCE/$DEST/g" "$3" > "${3//$SOURCE/$DEST}"
        rm "$3"
    else
        mv "$3" "${3//$SOURCE/$DEST}"
    fi
    exit
fi

if [ "$#" != "2" ] ; then
    showHelp
    exit
fi

if [ ! -d "$SOURCE" ] ; then
    echo "Error:  $SOURCE does not exist, exiting program"
    exit
fi

if [ -e "$DEST" ] ; then
    echo "Error:  $DEST already exists, exiting program"
    exit
fi

# copy all of the files
cp -r "${SOURCE}" "${DEST}"

# rename any file that contains the source dir name 
find "${DEST}" -type f -iname "*${SOURCE}*" -execdir "$(pwd)/cloner.sh" "${SOURCE}" "${DEST}" '{}' \;
```
#!/bin/bash
# clone watchface changing names where required

# remember source and dest, trimming trailing / if needed
SOURCE=$(echo $1 | sed 's:/*$::')
DEST=$(echo $2 | sed 's:/*$::')

function showHelp {
    cat << EOF
./clone.sh source destination
Clone a existing "source" watchface to a new "destination" watchface.
The script copies and renames files that contain the "source" name and 
updates the watchface qml file to point to the renamed sources.

EOF
}

# the three-argument form is only intended to be used internally
if [ -f "$3" ] ; then
    if [[ "$3" == *.qml ]] ; then
        sed "s/$SOURCE/$DEST/g" "$3" > "${3//$SOURCE/$DEST}"
        rm "$3"
    else
        mv "$3" "${3//$SOURCE/$DEST}"
    fi
    exit
fi

if [ "$#" != "2" ] ; then
    showHelp
    exit
fi

if [ ! -d "$SOURCE" ] ; then
    echo "Error:  $SOURCE does not exist, exiting program"
    exit
fi

if [ -e "$DEST" ] ; then
    echo "Error:  $DEST already exists, exiting program"
    exit
fi

# copy all of the files
cp -r "${SOURCE}" "${DEST}"

# rename any file that contains the source dir name 
find "${DEST}" -type f -iname "*${SOURCE}*" -execdir "$(pwd)/cloner.sh" "${SOURCE}" "${DEST}" '{}' \;
```
#!/bin/bash
# clone watchface changing names where required

# remember source and dest, trimming trailing / if needed
SOURCE=$(echo $1 | sed 's:/*$::')
DEST=$(echo $2 | sed 's:/*$::')

function showHelp {
    cat << EOF
./clone.sh source destination
Clone a existing "source" watchface to a new "destination" watchface.
The script copies and renames files that contain the "source" name and 
updates the watchface qml file to point to the renamed sources.

EOF
}

# the three-argument form is only intended to be used internally
if [ -f "$3" ] ; then
    if [[ "$3" == *.qml ]] ; then
        sed "s/$SOURCE/$DEST/g" "$3" > "${3//$SOURCE/$DEST}"
        rm "$3"
    else
        mv "$3" "${3//$SOURCE/$DEST}"
    fi
    exit
fi

if [ "$#" != "2" ] ; then
    showHelp
    exit
fi

if [ ! -d "$SOURCE" ] ; then
    echo "Error:  $SOURCE does not exist, exiting program"
    exit
fi

if [ -e "$DEST" ] ; then
    echo "Error:  $DEST already exists, exiting program"
    exit
fi

# copy all of the files
cp -r "${SOURCE}" "${DEST}"

# rename any file that contains the source dir name 
find "${DEST}" -type f -iname "*${SOURCE}*" -execdir "$(pwd)/cloner.sh" "${SOURCE}" "${DEST}" '{}' \;
Source Link
Edward
  • 66.6k
  • 4
  • 118
  • 282

Bash script to clone directory structure with renaming

I've written a script to aid in creating new watchfaces for the awesome AsteroidOS project. A watchface there typically consists of directory structure like this:

digital-shifted/
└── usr
    └── share
        ├── asteroid-launcher
        │   ├── watchface-img
        │   │   ├── asteroid-logo.svg
        │   │   ├── digital-shifted-0.png
        │   │   ├── digital-shifted-1.png
        │   │   ├── digital-shifted-2.png
        │   │   ├── digital-shifted-3.png
        │   │   ├── digital-shifted-4.png
        │   │   ├── digital-shifted-5.png
        │   │   ├── digital-shifted-6.png
        │   │   ├── digital-shifted-7.png
        │   │   ├── digital-shifted-8.png
        │   │   ├── digital-shifted-9.png
        │   │   └── digital-shifted-ring.svg
        │   └── watchfaces
        │       └── digital-shifted.qml
        └── fonts
            ├── OpenSans-CondLight.ttf
            └── OpenSans-Light.ttf

If we want to clone this watchface, named digital-shifted to a new watchface, let's say digital-swirl we need to copy that complete directory tree, but everywhere digital-shifted appears in a file name, we need to change it to digital-swirl and finally, the lines within the QML file that refers to those files should also be changed to refer to the renamed files. This is a fairly common operation for creating a new watchface from an existing one, so this script is intended to perform that task. It must be invoked in the same top-level directory that contains digital-shifted and the new digital-swirl must not already exist. The copying is fairly straightforward, but then find is used and the script runs itself with a third argument which is the name of each individual file that contains the original name. That part is not so obvious and is, in particular, the place I'd like comments and suggestions.

#!/bin/bash
# clone watchface changing names where required

# remember source and dest, trimming trailing / if needed
SOURCE=$(echo $1 | sed 's:/*$::')
DEST=$(echo $2 | sed 's:/*$::')

function showHelp {
    cat << EOF
./clone.sh source destination
Clone a existing "source" watchface to a new "destination" watchface.
The script copies and renames files that contain the "source" name and 
updates the watchface qml file to point to the renamed sources.

EOF
}

# the three-argument form is only intended to be used internally
if [ -f "$3" ] ; then
    if [[ "$3" == *.qml ]] ; then
        sed "s/$SOURCE/$DEST/g" "$3" > "${3//$SOURCE/$DEST}"
        rm "$3"
    else
        mv "$3" "${3//$SOURCE/$DEST}"
    fi
    exit
fi

if [ "$#" != "2" ] ; then
    showHelp
    exit
fi

if [ ! -d "$SOURCE" ] ; then
    echo "Error:  $SOURCE does not exist, exiting program"
    exit
fi

if [ -e "$DEST" ] ; then
    echo "Error:  $DEST already exists, exiting program"
    exit
fi

# copy all of the files
cp -r "${SOURCE}" "${DEST}"

# rename any file that contains the source dir name 
find "${DEST}" -type f -iname "*${SOURCE}*" -execdir "$(pwd)/cloner.sh" "${SOURCE}" "${DEST}" '{}' \;
```