4
\$\begingroup\$

This script goes through all svg files in an assets folder and compares them to the exported layers (one level above). If the svg timestamp is newer, it will automatically export the svg using inkscape (it will fetch the image size from the file name or set it to 1000 Pixel). It all works well, but I would be interested in optimizing the speed and the memory usage of this script.

The script is called inside brackets as in:

  #  "command-line-shortcuts.commands": [
  #      {
  #          "name": "Export all recently changed images",
  #          "dir": "$PROJECT_ROOT",
  #          "cmd": "PNG_export_AUTO.sh $SELECTED_ITEM",
  #          "shortcut": "Ctrl-Alt-B"
  #      }

but if several layers (over 50 layers with 2000 Pixel each) are exported, it will crash brackets.

Therefore I am particularly interested in optimizing this line inside the loop:

 png-export.py -p '^layer\d+$' -t png -X '-C -j -y 0 -w '$width $i

The format for the fileNames is: _show_showName.php and for the svg files: filenName_width.svg

This is the script:

# Find out which show is exported by using $SELECTED_ITEM passed to this script as $1
show=$(echo "$1" | awk '{split($1, arr, "[_.]"); print arr[3]}')
# check if the file Name contains the keyword SHOW on position two:
check=$(echo "$1" | awk '{split($1, arr, "[_.]"); print arr[2]}')
if [[ $check == "show" ]]
then
# export SHOW
echo "Exporting show:" $show
directory="web/images/$show/assets/"
# Change into the assets directory and work from there
cd $directory

# Loop through all svg files and export if necessary
for i in $(find . -name '*.svg' );
do
    # Capture the fileName for the current svg file
    fileName=$i
    echo "Analysing:" $fileName
    # Test if fileName contains any numbers
    if echo "${fileName}" | grep '[0-9]' >/dev/null; then
      # There are numbers -> set fileBase by cutting after the first underscore from the end
      fileBase=${fileName%_*}
    else
      # There are no numbers -> set fileBase via basename
      fileBase=$(basename "$fileName" .svg)
    fi
    #find the corresponding png file
    layerFile="$fileBase""_layer1.png"
    # check if file does not exist yet, if so set variable timestamp to UNIX beginning
    if [ ! -f ../$layerFile ]; then
    timestamp2=1
    else
    # If file exists capture timestamp
    timestamp2decimal=$(find ../$layerFile -type f -printf '%T@ %p\n' | cut -f1 -d" ")
    timestamp2=${timestamp2decimal%\.*}
    fi
    # Assign the unix time stamp of the svg to variable timestamp
    timestamp1decimal=$(find $i -type f -printf '%T@ %p\n' | cut -f1 -d" ")
    # Cut off the decimal points from the time stamp to enable arithmetic operations
    timestamp1=${timestamp1decimal%\.*}
    # Testing:
    # echo $timestamp1
    # echo $timestamp2
    # Compare the timestamp between both files and export if svg is newer than svg
      if (($timestamp1 > $timestamp2)); then
      # Find out which width is needed by deleting first dot from right and last underscore from left
      width="${fileName%.*}";
      width="${width##*_}";
      echo $width
      # the old way of just extracting numbers: width=${fileName//[^0-9]/}
        # test if the width is set in numbers for the file, otherwise set it to 1000
        re='^[0-9]+$'
        if ! [[ $width =~ $re ]] ; then
        width="1000"
        # Testing:
        #echo "width was set to 1000 as a standard"
        fi
      # export the PNG using inkscape export script:
      png-export.py -p '^layer\d+$' -t png -X '-C -j -y 0 -w '$width $i
           # Parameters passed on
           # SVG-Exports:
           # -p pattern: add layer and number
           # -t png export png
           # -X pass extra parameter to inkscape
           # Inkscape Exports
           # -C, --export-area-page
           # -j, --export-id-only, meaning export layer only
           # -y, --export-background-opacity
           # -w, --export-width
      echo $fileName "exported with" $width "Pixel, now preparing and moving the layers"
        # Move the layer files and remove the width from the layer name
        for i in $(find . -name '*layer*' );
        do
        mv -v $i ../${i/_$width/}
        done
    # end condition file needs to be exported:
    fi
done
# if the file name contains no show:
else
echo "Aw, snap! The file selected is no show!"
fi
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Review. Weird and inconsistent indentation makes this harder to follow. Indenting the true/false parts of your ifs would help considerably. \$\endgroup\$
    – chicks
    Commented Oct 16, 2017 at 1:51

1 Answer 1

2
\$\begingroup\$

There's a word-splitting issue here:

 for i in $(find . -name '*.svg' );

Since this is Bash, we can use an array variable to make this work robustly for all filenames:

readarray -d '' files < <(find . -name '*.svg' -print0)
for i in "${files[@]}"

The timestamp operations look convoluted relative to simply comparing directly using test -nt:

file1 -nt file2

True if file1 is newer (according to modification date) than file2, or if file1 exists and file2 does not.

There's already a good utility for updating files from their dependencies - consider using Make instead of shell for this.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.