Appending a text string to every document in a folder

I have looked and cannot find a way to use search and replace (or any other function) to add a text string at the end of every document in a folder.

Specifically, I keep the texts for my long-time online photo diary project in a Scrivener project, with one file for every day. Each file has some inline code at the top (for a Wordpress function) which includes the date etc. I have created the files for 2023, in monthly folders, but forgotten to add a “—TAGS—” string at the bottom of every day.

The result? I forget to add the tags I need more often than I don’t.

I know I can go through manually month by month, or less painfully, at the start of every week. Is there a way I can (semi) automatically add a “—TAGS—” string at the end of every so-far unused daily page?

If your “unused pages” are just blanks that have nothing different from one to the other, you could create a document template (with your string(s) properly positioned in it) and use that instead for upcoming days.

Sadly (for my current dilemma) they are not blank. As I said they each have a date-stamp block at the top of the page which is used in a php function in ClassicPress. This is date specific and some use of search and replace is needed to set up each year. Tomorrow’s header, for example, looks like this:

[dailyml place=“Here” year=“2023” month=“03” day=“13” time=“12:34”]

where place will be changed when I enter the text but the other values have been pre-calculated. I should have added the tags block as part of this process but I forgot :crazy_face:

Find a pattern that is common to all of those pages and that leads (but exclusively) to where the tag should have been.
Then use project replace ? (Set the scope for selected documents only.)

Say you have [dailyml place=“Here” year=“2023” month=“03” day=“13” time=“12:34”] at the top.
Then 8 empty lines.
Then the tag should have been there.

Replace 8 carriage returns by
→ 9 carriage returns + your string/Tag

(Of course, backup your project first, before risking messing things up. Sometimes it causes issues elsewhere, and you only realize later on.)

1 Like

Regular Expressions should be able to solve this, but it’s unclear what the string to search for is, and what you exactly want to replace it with…

What I want to replace it with is easy. I want to replace it with ”—- TAGS —-” without the quote marks.

The string to search for appears harder to nail. In effect I want to search for ”end of file” and insert a return and the above string just before the file ends.

Does that make sense?

Yes and no.
There is no searchable such as “end of file”.

Can you post a screenshot of one of your files with “Show invisibles” turned on ?
(But if your files are not all the same, don’t bother.)

(Caution: I’m writing this from a Mac. Win Scrivener commands may be different.)

I’m not sure I understand why a document template won’t work.

Create a template that includes the datestamp block that will ultimately be filled in with search and replace, PLUS the – TAGS – string.

Create as many documents from the template as you like. Use search and replace to fill the datestamp block as you’ve been doing. Leave the TAGS string alone.

You can locate existing documents that don’t have the string by using the inverse project search. Search for the string, then use the “Invert Results” option.

Once you have that, you can use the Edit → Append Selection to Document command.
Alternatively, create a document that contains ONLY the TAGS string. Duplicate it as many times as necessary so that you have a copy of it after every TAGS-less document. Then use the Documents → Merge command to glue the existing document and the string together.

It’s a bit messy, but you can also use the Compile command for bulk editing of existing documents. Compile using a Section Layout that adds the TAGS string as a document suffix. Then use the Import and Split command to re-import the result. (I’d recommend importing to an otherwise empty project in case the results are unexpected.)

From the Scrivener point of view, the “normal” place to put all of this information would be in the document metadata, not the body text. So just put whatever tags you want in the Keywords field. Whether that will work in this case depends on what you ultimately plan to do with the information, though.

2 Likes

There is no searchable such as “end of file”.

Hi V_V,

I haven’t used regular expressions in Scrivener, but I have used it elsewhere (programming). There is a pattern you can search for to find the end of a file (document?). You can use ‘\%$’ (without the tick marks).

There is also a pattern for the start of a file (document?). This StackExchange article describes both.

Thx,
Tom

2 Likes

Good to know.
I was actually referring to plain old search (I know close to nothing RegEx-wise).

I’ll add it to my bank of formulas. :slight_smile:

Actually, there is some discussion on this. I will try a few example of my own and confirm.
Tom

Sure enough. It looks like there are two options within Regular Expressions that would be of interest.

  1. ‘\Z’ finds the end of the text (non-EOL) within the file.
  2. ‘\z’ find the end of the file.

And sure enough, it does not look like these are implemented in Scrivener.


– fixed the screen shot –

Too bad. Would be a useful tool.

Tom

Your screenshot differs than what you typed though. (?)
\ vs/

Nice prose btw :wink:

Good call. Screen shot fixed.

And thanks, I’m writing in mock Kingon! :laughing:

Is this doing what you want?

Due to incomplete implementation of the RegEx Replace function in Find (Ctrl/Cmd+F), you have to use Project Replace with the RegEx Scope to make this work in Scrivener:


Replace:
\[dailyml place=“(.+?)” year=“(\d\d\d\d)” month=“(\d\d)” day=“(\d\d)” time=“(\d\d):(\d\d)”\]
With:
[dailyml place=“$1” year=“$2” month=“$3” day=“$4” time=“$5:$6”]

—TAGS—

The six Capturing Groups (…) ensure dynamic data is maintained in the results as $n.
Use Ctrl/Cmd+Enter for Carriage Returns, \n\n doesn’t work in Scrivener.

1 Like

@kewms The problem in reporting these kind of problems lies in how much backstory needs reporting to provide the context for the problem. I obviously didn’t include enough :grinning:

I have used templates throughout this process. In fact I have made an annual template that only needs the year finding-and-replacing every December 31. My problem lies in the fact that I changed the template last December to simplify it and then (for backstory reasons) wrote the photo caption paragraphs every day for January and February and half of March, but did not attempt to put them online until last weekend. Only then did I realise that my new, carefully constructed template was too simple.

So, slightly but not completely unpacked, my question was about whether I would have to remake the existing templates from scratch or whether I could find a quicker and simpler solution using Find and Replace. And it turns out I can!

Big thanks to @Vincent_Vincent @ThomasHSteine and @AntoniDol for giving me the regular expressions I needed.

3 Likes