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

@Inventsable, one question: Is there any difference between using {1,} and + as a Quantifier for \d or is it personal preference?

 


This forum keeps marking me as spam for making more than two edits to my posts! Super pedantic, I really dislike that.

 

There should be no difference in this context, but only because we know exactly the format of our intended string. The following would be identical:

 

/\scopy(\s\d{1,})?$/
/\scopy(\s\d+)?$/
/\scopy(\s\d*)?$/

 

Sorry, I had a much more detailed response earlier. Maybe it's still in the email notification if you've gotten it?

 

Btw, the original function I used could be further refactored so that the iterable list itself is a variable and using a single function. Notice that the function will call itself if layer.layers has length, has list = [] as a default param, and will assign app.activeDocuments.layers as the list if the function is called with no param (which should only happen at the first time). Since we know all iterable lists will be similar and we act on them the same, there's no reason not to try and use a single loop (but just change what we're looping through):

 

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)
    }
}
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.