DriveApp.searchFiles - Use any substring of filename to search for files - javascript

I am writing appscript code to search for files in my drive.
Below are files in my google drive.
t_abcd.txt
p_abcd_0211.txt
j_abcd.docx
bwt_abcd.txt
etc
Note that _abcd is common in all of the above and only the prefix and suffix change.
I want the search to find all the above files when the user searches for "abcd" or its substring.
In the documentation for DriveApp.searchFiles(params) I could not find anywhere regular expressions or substrings being used to search for files.
One solution would be to get all files from the drive and write separate logic to identify the required files.
Is there any simpler way to do this?
Please advise.

How about this workaround? Unfortunately, in the current stage, I think that there are no methods for directly retrieving the files with the such filenames. So for example, how about the following workaround?
Document of Search for Files says
fullText: Full text of the file including title, description, content, and indexable text.
The query which is used as the workaround is fullText contains '_abcd'. I think that when this is used as the search query, the process cost is lower than that of the full search. Sample script is as follows. I think that there are several workarounds for your situation. So please think of this as just one of them.
Sample script:
var q = "fullText contains '_abcd'";
var files = DriveApp.searchFiles(q);
while (files.hasNext()) {
var file = files.next();
var filename = file.getName();
if (filename.indexOf("_abcd") > -1) {
Logger.log(filename)
}
}
Reference:
Search for Files
If this was not what you want, I apologize.

With DriveApp.searchFiles(params) you can use title contains "X" to get your files without using regular expressions and without having to take extra steps needed when searching with fullText contains.
Building on Tanaike's answer, here's an example function that logs the names of all Drive files with names containing "_abcd":
function findFiles() {
var q = "title contains '_abcd'";
var files = DriveApp.searchFiles(q);
while (files.hasNext()) {
var file = files.next();
filename = file.getName();
Logger.log(filename)
}
}
References:
DriveApp.searchFiles
docs
Tanaike's answer

As of now the query behaves:
able to search abcd if file starts with it abcd_slide, abcd_sheets, abcd_doc.
able to search abcd if it is another word.
Cannot search it is a subtext doc_abcd, sheets_abcd, slide_abcd.
Try creating a bug, to clarify its function.

Related

Javascript optimizing regex function to extract sentences from a string containing a keyword

I currently have a function to take a string, break it up into sentences, then extract the sentences that contain a user defined keyword and return them:
function getSentencesWithWord(word, text) {
let sentenceArray = text.replace(/([.])\s*(?=[A-Z])/g, "$1|").split("|")
return sentenceArray.filter(sentence => sentence.includes(word))
}
Currently, this function works. However, the amount of text I need to search through with this function is quite large; it is searching through around 30 google docs that could each be up to 75 pages each, and searching for certain terms (such as the word "the") can take up to a minute for the function to complete. Is there a more optimized way to search through and extract this much text?
Edit:
Because someone asked in the comments, the word variable is just a string obtained from a text input on an HTML page and the text variable is a string obtained via this function in a Google Apps Script:
function getText(docID){
let doc = DocumentApp.openById(docID);
let textToSearch = doc.getBody().getText();
return textToSearch;
}
I have an array of all the google doc IDs I need to access and I just iterate over the array and obtain the text for each doc
The replace you've provided, replace(/([.])\s*(?=[A-Z])/g, "$1|"), didn't work for me == got the same string without change...
How about this:
("|"+text.toLowerCase().replace(/\s/g, "|")+"|").includes("|"+word.toLowerCase()+"|")
Or, this:
("|"+text.toLowerCase().split(" ").join("|")+"|").includes("|"+word.toLowerCase()+"|")
Was unable to find a faster method of achieving this with Google Apps Script so I just went back to Node.js and ended up using the Google Drive API to download the files as .txt files, which are much smaller and so I can search through them much faster now

How to replace a string with a generated number in multiple text files automated and save them named as the value?

I have javascript file named w1.js, in the code there is a
var IDInput = '1'; .
I would like to generate few hundred .js files, changing only that value and save them as separate file.
Like:
w2.js file with var IDInput = '2';
w3.js file with var IDInput = '3'...so on.
Using the software fileboss I'm able to generate duplicates of the same .js file as I wanted, w1.js,w2.js,w3.js..but changing the code "var IDInput = 'x';" in them manually using notepad++ is a lot, the number in the name of the file and the value of the variable needs to match.
Please note "var IDInput = '1';" is on line 10 in my code, so replacing the line could be an option using a tool or I can set it as a unique string (many other variables are in the code that need to remain intact).
Any ideas?

String replace function isnt responding

I am writing a photoshop script in JS, at this point I ask the user to select and folder location and add all those files to an array. I wish to then parse the array so only the filename remains.
I get this error : fileList[i].replace is not a function
I imagine its due to me passing in the wrong value or using the wrong type. Was hoping someone could explain the issue and help me resolve it please?
//Prompt for folder location
var Path = Folder.selectDialog("Select Folder Location for Renders")
// Use the path to the application and append the samples folder
var samplesFolder = Folder(Path)
var fileList = samplesFolder.getFiles()
for (var i = 0; i < fileList.length; i++)
{
fileList[i] = fileList[i].replace(/^.*[\\\/]/, '')
}
prompt("Complete")
Thanks for your time, AtB
S
The error is occuring because you're expecting a string, and it isn't one.
http://jongware.mit.edu/idcs5js_html_3.0.3i/idcs5js/pc_Folder.html says that getFiles
returns an array of File and Folder objects, or null if this object's referenced folder does not exist.
Fortunately, both File and Folder have these properties:
fsName - The platform-specific full path name for the referenced file
fullName - The full path name for the referenced file in URI notation.
name - The file name portion of the absolute URI for the referenced file, without the path specification
Of course, if you don't want any of the path, and just want the filename, use name, otherwise, use the replace command on whichever suits you - fsName or fullName.
So - in your loop, you want:
fileList[i] = fileList[i].name
You may want to filter out the Folders in your end result. That would entail something like this inside your loop:
if (fileList[i] instanceof Folder) {
fileList.splice(i, 1);
--i; // go back one i, because you just removed an index. Note, if you're not careful, such shenanigans may mess up the second term of the for loop.
continue;
}
One last suggestion: I would personally find it cleaner to make a new array, rather than doing the replacement in position. The language certainly supports what you're doing, but it still makes me twitch to go from File or Folder array to string array. (Granted, you thought you were doing string array to string array.) This would also simplify any issues with removing indices for folders, etc.

Converting variable in javascript to a CSV file

Basically I have a string variable that is composed of two other variables separated by a comma:
item = "Pencil";
amount = 5;
entry = item + "," + amount;
*export entry to csv
So the "entry" variable should be in the correct format to save as a comma separated file. Is there some command that will take this variable and save it as a csv, or any other format easily opened in a spreadsheet for later use? The entry variable will change and the new information will need to be appended to the csv file if it already exists. So let's say if we also had:
item = "Paper";
amount = 25;
entry = item + "," + amount;
*export entry to csv
The resulting csv file should be:
Pencil,5
Paper,25
I've done a bit of searching through other questions, but most folks seem to be trying to do more complex things (e.g., dealing with server vs. client-side issues) while I'm just trying to figure out how to get data I'm working on my own computer in javascript to a saveable file. Seems like that isn't the case for many questions being asked though. I'm sure there's a simple answer out there and hopefully just a single command or two. However, I've been wading through a lot of semi-related posts that aren't too clear, so I figured this would be quicker.
It is perfectly possible, using some FileSaver implementation. I believe it exists natively on IE10, but still needs a shim on other browsers.
I've written a light-weight client-side CSV generator library that might come in handy. Check it out on http://atornblad.se/github/ (scroll down to the headline saying Client-side CSV file generator)
As I said, it requires a functioning FileSaver implementation handling calls to window.saveAs(). Check out Eli Grey's solution on http://eligrey.com/blog/post/saving-generated-files-on-the-client-side
When in place, you simply generate and save CSV files on the fly like this:
var propertyOrder = ["name", "age", "height"];
var csv = new Csv(propertyOrder);
csv.add({ name : "Anders",
age : 38,
height : "178cm" });
csv.add({ name : "John Doe",
age : 50,
height : "184cm" });
csv.saveAs("people.csv");

Determining the presence of a file with JavaScript?

I have folder/file tree generated by JavaScript where the folder and files each have checkbox inputs with paths associated with them, like:
/var/www/site/user/folder7/ or
/var/www/site/user/folder7/file.txt or
/var/www/site/user/folder7/file.? (? being any file extension)
In the case of these paths I need only
/var/www/site/user/folder7
I know that normally to remove file names one would use something like:
var full_path = node.context.nextElementSibling.value;
var folder_target_path = full_path.substring(0, full_path.lastIndexOf("/"));
However this return either:
/var/www/site/user/folder7 or
/var/www/site/user
I could use the lastIndexOf() method if I could use some regex to find .? and then up to the last '/'; however I am fairly new to javascript and have never used regex in it.
Could you suggest an effecient way to get only the folder and not the file path in all cases?
Regards,
Steve
Here's the W3 tutorial on JavaScript and regex:
http://www.w3schools.com/jsref/jsref_obj_regexp.asp
var folder_target_path = full_path.replace(/\/[^\/]*$/, '');
will remove the last / and anything following it. I think you can avoid having to escape the /'s in the pattern by creating a Regexp object from a string.
To get this working completely I need to use the following:
var full_path = node.context.nextElementSibling.value;
var folder_target_path;
var pathRE = /\./;
if (full_path.match(pathRE)){
folder_target_path = full_path.replace(/\/[^\/]*$/, '');
} else {
folder_target_path = full_path;
}
This either matches a path that contains . (period to designate file extension start) then remove the file name with full_path.replace(/\/[^\/]*$/, ''); otherwise don't modify the full path.
Thanks to all!
Regards,
Steve

Categories