Find & replace in files within a folder using Google Apps Script - replace

Could you post a Snippet that does find & replace across all files within a folder please?
I did find something similar,
Google Scripts - Find and Replace Function that searches multiple documents
but that one search in every file in Google Drive, not within a folder. Since I'm only learning Google Apps Script by example now, I can't make that tiny step myself.
EDIT: Further on the replacing part.
The DocumentApp.openById returns a type of Document right?
However, I can't find the replaceText method in the Document type doc:
https://developers.google.com/apps-script/reference/document/document
Fine, I then dig deeper, and found another example,
Google Apps Script document not accessible by replaceText(), which indicates that the replaceText method should be invoked from var body = doc.getActiveSection(). However, I can't find the getActiveSection method in the Document type doc either.
Please help. thx

The first thing is to get a hold of your folder, this can be done in a few ways.
If you are writing a script for a limited audience, and you are working with only a particular folder you can use DriveApp.getFolderById(id). The id can be found in the url of your drive web app when you navigate to a folder as such:
https://drive.google.com/a/yourcompany.com/?tab=mo#folders/0B5eEwPQVn6GOaUt6Vm1GVjZmSTQ
Once you have that id, you can simply using the same code in the answer you reference, iterate through the file iterator for that particular folder as such:
function myFunction() {
var files = DriveApp.getFolderById("0B5eEwPQVn6GOaUt6Vm1GVjZmSTQ").getFiles();
while (files.hasNext()) {
var file = files.next();
Logger.log(file.getName());
var doc = DocumentApp.openById(file.getId());
doc.replaceText("My search string or regex", "My replacement string");
}
Logger.log("Done")
}
Alternative way of getting the folder if you only know its name are the use of DriveApp.getFoldersByName(name) which returns a folder iterator. If you know you have only one folder of that name, then you need to simply get the first and only element in the iterator as such:
function myFunction() {
var folders = DriveApp.getFoldersByName("myfoldername");
var myFolder = null;
if (folders.hasNext())
myFolder = folders.next();
if (myFolder !== null) {
// do stuff
} else {
// exit gracefully
}
Further if you have multiple folders with the same name, you would have to iterate through them in a while loop (similar to the file iterator in the code you linked) and find a marker that proves this is the folder you are looking for (i.e. you could have an empty file with a particular name in there)

Related

How to search files in google drive using apps script based on custom keyword with regex?

I have script to search file in google drive with apps script based on keyword.
e.g. I want to search file that contains "FX.ABCDEF".
I using fullText contains {text}.
Here the code :
var searchFiles = DriveApp.searchFiles('fullText contains "FX.ABCDEF" ')
On the other hand many keywords are similar to FX.ABCDEF. Characters after FX. is dynamic. Therefore I don't want to define keywords like that over and over again. So in cases like this a simplification is needed using regex.
So we can write :
/FX\.[A-Z]+/g
I'm still confused about implementing regex in searchFiles.
Searching in Drive files contents using regex is not currently supported. Here is the list of the available search syntax for Drive file contents.
If this feature is really important for your application consider filing a Feature Request here.
Get all files, put their names in array and do RegEx search inside this array:
function myFunction() {
var files = DriveApp.getFiles();
var file_names = [];
while (files.hasNext()) file_names.push(files.next().getName());
var reg = /.FX\.[A-Z]+/g;
var found_names = file_names.filter(n => reg.test(n));
Logger.log(found_names);
}
This way you will get the array with wanted names. You can take names from this array and get the file by the name. But keep in mind -- there can be many different files with the same name. You have to handle this collision some way.

filesyncprovider creates folders for documents with same name as document

I am building a sync app with a customprovider and a filesyncprovider. I based my provider on this example:
https://code.msdn.microsoft.com/File-Sync-with-Simple-c497bf87
Now I want to extend to a hierarchical folderstructure. So in the EnumerateItems method of the custom syncprovider I return all files and folders just like I did before with only the files in the directory. Now on the filesyncprovider side, this results in a creation of folders with the name of the file and the file being placed in this folder. E.g.
Folder1\textfile.txt\textfile.txt
I have no idea, what I am doing wrong and I find it hard to know the part of the MS filesyncprovider where I could debug to see, what's happening.
My question is, what am I doing wrong and how can I correct it, so that the correct output would be
Folder1\textfile.txt?
Best regards,
Tobias
// Must return the relative path without the filename
public string RelativeDirectoryPath
{
get
{
return _relativeFilePath;
}
Read first - then ask: I returned the path to the file instead of the path to the folder... comment above even warns not to do that...

Get a list of available components

I'm writing an admin tool for a ColdFusion app, and I'd like to provide an autocomplete feature for a field for entering component names. In order to do this, I'd need a list of all of the components in the application. I have the following code to get a list of mappings:
public function getComponentNames() {
var ServiceFactory = CreateObject('java', 'coldfusion.server.ServiceFactory');
return ServiceFactory.runtimeService.getMappings();
}
Is there any better way to get a list of components than crawling the filesystem looking for .cfc files under these paths?
EDIT: This is currently working, but painfully slowly for just a couple of thousand components:
public function getComponents() {
var ServiceFactory = CreateObject('java', 'coldfusion.server.ServiceFactory');
var mappings = ServiceFactory.runtimeService.getMappings();
for (m in mappings) {
var components = DirectoryList(mappings[m], true, 'path', '*.cfc');
writeDump(components);
}
}
In CFML the sense of an "application" is pretty loose. It's more a bunch of files that interact with each other.
As well as scanning all the mappings, you'd also need to scan any directories within the subdirectory structure of the site as well.
Are you not better off - perhaps - writing an extension for Sublime Text or Eclipse or something? You can then leverage their idea of "projects", and you can let the IDE handle the file indexing. You can then just "do stuff" with the file listing the IDE will expose to you via the API. I've never written an IDE extension, so can't be more "helpful" than that, I'm afraid.

Google Scripts - Find and Replace Function that searches multiple documents

I'm new to Google Scripts and am looking for a good place to start and educate myself on being able to write a script that accomplishes the following:
It scans a number of different google docs and does a find and replace, essentially a mail merge, as instructed by the code. So basically each doc would have a [REPLACE TEXT HERE] already in it and I'd tell the script that I'd like each [REPLACE TEXT HERE] changed to [WORD A] for a number of different documents.
I understand this is may be a basic request, so if there's a place to point me towards that walks me through google script basics that would include this, that'd be great - my initial research did not have anything that honed in exactly on this specific need.
Thanks for your help everyone!
Here's how I did it. (I learned how to use the API from the documentation.)
function myFunction() {
var files = DriveApp.getFiles(); // Note: this gets *every* file in your Google Drive
while (files.hasNext()) {
var file = files.next();
Logger.log(file.getName());
var doc = DocumentApp.openById(file.getId());
doc.replaceText("My search string or regex", "My replacement string");
}
Logger.log("Done")
}

BitBucket Wiki: Create a hierarchy structure?

I want to create a hierarchy in my wiki like so:
General
FooPages
Foo1
Foo2
Foo3
ODP
Bar
Baz
I would like to create these pages, and use <<toc>> table of contents macros to organize them.
How can I do that? Do I need to clone and edit the wiki on my own machine, or can I do that exclusively through the web interface?
You can (partially) do this, using <<toc / >>.
This will create a TOC for all the headers in files in the root directory.
It will not list headers in file in the sub directories, though.
You can do the same for <<toc FooPages/ >> etc.
You can do this both through the web interface and locally on your machine.
I placed some TOC examples on this Bitbucket wiki page: http://bitbucket.org/marijnvanderzee/build-wiki/wiki/TocTests. You can view the markup there.
Make sure to balance the equal signs on you headers; e.g. use == H2 == instead of == H2.
Both are valid, but at this time, the latter is not recognized by the <<toc>> macro.
Regarding the hierarchy side of this question, it's worth clarifying:
You can create a hierarchical structure by using the Title field when you create or edit a wiki page.
Eg: If you want to create a new file Bar.md inside a new Foo directory, just create a new page and in the Title field write "Foo/Bar.md". It will create the directory and the file at the same time.
I'm not sure if there's a way to just create the directory without adding a file to it straight away.
Regarding the TOC half of this question, I found that I can use the # HeaderTitle syntax in Markdown pages, and Creole's TOC macro will recognise it.