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
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
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
December 21, 2023

You need enough RAM.

Open all documents and find & replace in all document.

Masoud Moghaddam
Inspiring
December 21, 2023

Unfortunately, I don't have sufficient RAM – only 4GB! If a script could handle the task by opening and closing documents individually for modification, that would be ideal.

Willi Adelberger
Community Expert
December 21, 2023

To work professional with InDesign you need to expand the RAM. 4GB is enought to select the text tool, but not more.