Skip to main content
Known Participant
December 30, 2019
Answered

Script to remove the word 'copy' from layer text

  • December 30, 2019
  • 2 replies
  • 3779 views

I use very specific titles for my illustrator files and do a lot of duplicating layers, which in many cases creates the word 'copy' after the layer. 

For example:

Layer 1

 - Sublayer 1

 - Sublayer 2

Layer 1 copy

 - Sublayer 1 copy

 - Sublayer 2 copy

 

It's easy enough to remove from a few layers, but sometime's I need to remove it from hundereds of layers. Is there either: an option to turn that off, or a script that either removes the word copy or allows me to rename layers easily?

I've looked around for quite a bit and can't seem to find anything related.

I use a script to rename individual objects, but can't seem to make it work for layers.

This topic has been closed for replies.
Correct answer rcraighead

Edited:
This function will update main and sublayer names. Still working to incorporate possible "copy 2" names, etc.

 

 

 

updateLayerNames();

function updateLayerNames() {
  var aDoc = app.activeDocument;
  var i;
  var ii;
  for (i = 0; i < aDoc.layers.length; i++) {
    aDoc.layers[i].name = aDoc.layers[i].name.replace(" copy", "");
    for (ii = 0; ii < aDoc.layers[i].layers.length; ii++) {
      aDoc.layers[i].layers[ii].name = aDoc.layers[i].layers[ii].name.replace(" copy", "");
    }
  }
}

 

 

 

 

 

 

2 replies

rcraighead
Legend
December 31, 2019

@joer74233125

I'm sure there's a more elegant way, but this will take care of 3 levels of copied layer names. Add a " copy 4" line if you think you need it.

 

Edit: Forgot to add lines for "Main Layers" as well.

updateLayerNames();

function updateLayerNames() {
  var aDoc = app.activeDocument;
  var i;
  var ii;
  for (i = 0; i < aDoc.layers.length; i++) {
    aDoc.layers[i].name = aDoc.layers[i].name.replace(" copy 3", "");
    aDoc.layers[i].name = aDoc.layers[i].name.replace(" copy 2", "");
    aDoc.layers[i].name = aDoc.layers[i].name.replace(" copy", "");
    for (ii = 0; ii < aDoc.layers[i].layers.length; ii++) {
      aDoc.layers[i].layers[ii].name = aDoc.layers[i].layers[ii].name.replace(" copy 3", "");
      aDoc.layers[i].layers[ii].name = aDoc.layers[i].layers[ii].name.replace(" copy 2", "");
      aDoc.layers[i].layers[ii].name = aDoc.layers[i].layers[ii].name.replace(" copy", "");
    }
  }
}

 

 

This could be made more editable with the use of a few variables. 🙂

Inventsable
Legend
December 31, 2019

Hi @rcraighead, you could use Regex to handle the copy suffixes and recursion to handle the depth:

 

updateLayerNames()

function updateLayerNames() {
  var aDoc = app.activeDocument;
  for (var i = 0; i < aDoc.layers.length; i++)
    updateLayerName(aDoc.layers[i])
}

function updateLayerName(layer) {
  layer.name = layer.name.replace(/\scopy(\s\d{1,})?$/g, "");
  for (var i = 0; i < layer.layers.length; i++)
    updateLayerName(layer.layers[i])
}

 

This will handle any " copy" no matter the depth or number, see RegEx example here.

Inventsable
Legend
January 1, 2020

Yes, I read your earlier post. I was trying to retrieve it.
Your explanations are so helpful! I'm new to recursion so digging into that.

FYI… I'm getting an error when running the latest version: "Expected: )".
Haven't been able to determine the cause.


Hmmm, are default parameters not supported in JSX? I tend to write in Typescript and compile down so occasionally I'm prone to throw in some unsupported syntax. Try this:

updateLayerNames()

function updateLayerNames(list) {
    if (arguments.length < 1) list = app.activeDocument.layers;
    for (var i = 0; i < list.length; i++) {
        list[i].name = list[i].name.replace(/\scopy(\s\d{1,})?$/g, "");
        if (list[i].layers.length) updateLayerNames(list[i].layers)
    }
}

 

Or this:

 

updateLayerNames([])

function updateLayerNames(list) {
    list = list.length ? list : app.activeDocument.layers;
    for (var i = 0; i < list.length; i++) {
        list[i].name = list[i].name.replace(/\scopy(\s\d{1,})?$/g, "");
        if (list[i].layers.length) updateLayerNames(list[i].layers)
    }
}

 

Why not use VSCode instead of the very old ESTK? It's a very beautiful experience to code in VSCode especially alongside your panel JS code, I also have a few tools you're welcome to use like Scriptopia which handles all of the setup for Typescript to allow you to see the Illustrator DOM and autocomplete as you type alongside compiling ES6 methods down to their JSX counterparts. If you'd like an example of how this works, here's an online code editor specific to Illustrator, I have a panel version of this as well so you can write and run code directly inside Illustrator and even use ES6 methods for scripting.

rcraighead
rcraigheadCorrect answer
Legend
December 31, 2019

Edited:
This function will update main and sublayer names. Still working to incorporate possible "copy 2" names, etc.

 

 

 

updateLayerNames();

function updateLayerNames() {
  var aDoc = app.activeDocument;
  var i;
  var ii;
  for (i = 0; i < aDoc.layers.length; i++) {
    aDoc.layers[i].name = aDoc.layers[i].name.replace(" copy", "");
    for (ii = 0; ii < aDoc.layers[i].layers.length; ii++) {
      aDoc.layers[i].layers[ii].name = aDoc.layers[i].layers[ii].name.replace(" copy", "");
    }
  }
}

 

 

 

 

 

 

Known Participant
December 31, 2019

This is awesome, thank you!

Getting 'copy' out of the sublayers would be incredible, it's such a time consuming process by hand.

 

If removing 'copy #' is too much, it's not a big deal.  I use an action to duplicate layers, so I can easily add the 'remove copy' script as part of the action, so it'll remove it as I go. Otherwise I can just duplicate your script down and change (" copy", ""); to (" copy 2", "");, (" copy 2", "");, ect.

 

Edit: Updated while I was responding. This is exactly what I was looking for, you're a lifesaver.

rcraighead
Legend
December 31, 2019

See update. Still does not address # suffixes when a layer is copied multiple times. I'll see if I can figure that out. Glad it helps.