Skip to main content
Masoud Moghaddam
Inspiring
December 21, 2023
Answered

How can I efficiently find and replace a word or phrase across multiple documents within a book file

  • December 21, 2023
  • 2 replies
  • 1585 views

Hi,

 

I have a book file consisting of over 300 documents, and I've realized the need to replace certain words and phrases with their corrected and modified versions. Going through the Find/Replace window for each document individually is time-consuming and tedious. Is there a way to automate this process for all documents in the book using a script or possibly GREP?

Correct answer rob day

You should be able to do it by storing the pairs in a nested array—the format would be:

var array = [["search1", "change1"], ["search2","change2"],...]
 
Maybe this works?
//A nested array in this format [["search1", "change1"], ["search2","change2"],...]
var sa = [["indesign", "InDesign"], ["script panel","Script Panel"], ["graphic objects", "artworks"]]

searchBooks()

function searchBooks(){
    try {
        var b = app.activeBook
    }catch(e) {
        alert("No Open Books")
        return
    }  
    var bp = b.bookContents.everyItem().fullName;
    var d;
    for (i = 0; i < bp.length; i++) {
        d = app.open(bp[i]);
        
        for (var j = 0; j < sa.length; j++){
            grepSearch(sa[j][0],sa[j][1])
        };   
        d.close(SaveOptions.YES);
    }
}

/**
* Document Grep find and change 
* @ param f the find grep string 
* @ param c the change grep string
* @ return void 
*/
function grepSearch(f,c){
    app.findGrepPreferences = app.changeGrepPreferences = app.findChangeGrepOptions = null;
    app.findChangeGrepOptions.properties = {includeFootnotes:true, includeHiddenLayers:true, includeMasterPages:true, wholeWord:false} 
    app.findGrepPreferences.findWhat = f;
    app.changeGrepPreferences.changeTo = c;
    app.activeDocument.changeGrep( true )
}

2 replies

rob day
Community Expert
Community Expert
December 21, 2023

Hi @Masoud Moghaddam , For a simple text find and change you could try this—replace "Foo" and "Bar" with your find and change text. Should work at least back to CS6:

 

 

var gf = "Foo"
var gr = "Bar"

searchBooks()

function searchBooks(){
    try {
        var b = app.activeBook
    }catch(e) {
        alert("No Open Books")
        return
    }  
    var bp = b.bookContents.everyItem().fullName;
    var d;
    for (i = 0; i < bp.length; i++) {
        d = app.open(bp[i]);
        grepSearch(gf,gr)
        d.close(SaveOptions.YES);
    }
}

/**
* Document Grep find and change 
* @ param f the find grep string 
* @ param c the change grep string
* @ return void 
*/
function grepSearch(f,c){
    app.findGrepPreferences = app.changeGrepPreferences = app.findChangeGrepOptions = null;
    app.findChangeGrepOptions.properties = {includeFootnotes:true, includeHiddenLayers:true, includeMasterPages:true, wholeWord:false} 
    app.findGrepPreferences.findWhat = f;
    app.changeGrepPreferences.changeTo = c;
    app.activeDocument.changeGrep( true )
}

 

 

If you are using Grep strings, back slashes have to be escaped so, for example, to find multiple tabs this:

"\t+"

Needs to be this:

"\\t+"

 

Community Expert
December 21, 2023

Nice one, Rob. Just one comment: it's more efficient to keep the two lines that set the find/change preferences and options outside the for-loop because you need to set them just once.

 

P.

rob day
Community Expert
Community Expert
December 21, 2023

Thanks Peter, you‘re right, no need for the grepSearch() function, which I usually use for stringing together multiple searches—not sure if @Masoud Moghaddam needs more than one search. This would be better for a single search:

 

 

var gf = "Bar"
var gr = "Foo"

searchBooks()

function searchBooks(){
    try {
        var b = app.activeBook
    }catch(e) {
        alert("No Open Books")
        return
    }  
    var bp = b.bookContents.everyItem().fullName;
    app.findGrepPreferences = app.changeGrepPreferences = app.findChangeGrepOptions = null;
    app.findChangeGrepOptions.properties = {includeFootnotes:true, includeHiddenLayers:true, includeMasterPages:true, wholeWord:false}
    var d;
    for (i = 0; i < bp.length; i++) {
        d = app.open(bp[i]);
        app.findGrepPreferences.findWhat = gf;
        app.changeGrepPreferences.changeTo = gr;
        app.activeDocument.changeGrep( true )
        d.close(SaveOptions.YES);
    }
}

 

Willi Adelberger
Community Expert
Community Expert
December 21, 2023

You need enough RAM.

Open all documents and find & replace in all document.

TᴀW
Legend
December 21, 2023

I recently had to do something similar, and it seems that InDesign will not open more than 99 documents at once. I have 32GB and there was plenty left.

Quite dangerous actually, because I thought I had opened all documents and made the change in all of them. Afterwards I realized that only a fraction of the documents had been changed... I redid the operation to see what had happened, and that's where I get the number 99 from.

rob day
Community Expert
Community Expert
December 21, 2023

I wonder if it is still memory related? I can run a script that creates over 99 new documents without a problem :

 

var doc;
for (var i = 0; i < 115; i++){
    doc = app.documents.add();
};   

 

iMac with 72GB: