Delete lines by first character, i don't see regex support in find and replace?

Hi all

im trying to delete from certain files all lines that start with:

<link href="/Users/zeltak/MLT/css/prism.css" rel="stylesheet">

i thought to use regex and find replace any lines that starts with a <, even looked in the help but couldn’t see regex support in the DOCU (not that i really know what im doing with regex anyway… :slight_smile: :))

is there a neat way to select a bunch of MD files in Devonthink and then find and replace to delete certain lines?

best

Z

Applescript

1 Like

ok thx! @DTLow

i don’t really know how to use Applescript. any examples i can start lookin at and try to build upon

best

Z

Here’s a sample applescript
The first section
. retrieves the selected notes
. processes each note using a repeat loop
. retrieves the plain text of the note, edits, updates the note
The second section is a handler that does the editing
. splits the text by line using text delimiters
. processes each line using a repeat loop
. extracts lines based on criteria
. re-assembles the text

tell application id "DNtp"
	set selectedNotes to get selection
	repeat with theNote in selectedNotes
		set newText to my DropLines(plain text of theNote)
		set plain text of theNote to newText
	end repeat
end tell

on DropLines(oldText)
	set savedDelims to AppleScript's text item delimiters
	set AppleScript's text item delimiters to linefeed
	set textLines to text items of oldText
	set AppleScript's text item delimiters to savedDelims
	
	set newText to ""
	repeat with textLine in textLines
		if textLine does not start with "<" then ------- Criteria for dropping lines   
			set newText to newText & textLine & linefeed
		end if
	end repeat
	return newText
end DropLines
1 Like

Thanks for that - I had seen this post and started scripting in my head; I think I would have got it to work, but it wouldn’t have been anything like as tidy as what you’ve conjured up (I hadn’t thought to use the text item delimiters). I’ll be adding that to my little reference script collection :slight_smile:

wow @DTLow !!

this is perfect, cant thank you enough :smiley:

best regards

Z

Just for the heck of it and since you were asking for REs: The same could be achieved with JavaScript (though this will not work as external script in a smart rule!)

const app = Application("DEVONthink 3");
const records = app.selectedRecords();
records.forEach(r => {
  let txt = r.plainText();
  r.plainText = txt.replaceAll(/^<*.$/g,"");
})

It is, of course, a bit bland, compared to the baroque AppleScript version. And I didn’t test it at all, so I’m not sure that it works as is. But at least it’s a bit less to type and it might help @Blanc to get their weekly dose of parenthesis and such :stuck_out_tongue_winking_eye:

2 Likes

And because no one at all asked for it…

tell application id "DNtp"
	repeat with thisRecord in (selected records)
		if (type of thisRecord as string) = "markdown" then
			set recPath to (path of thisRecord as string)
			do shell script "sed -i '' -E '/^<.+>$/d' " & (quoted form of recPath)
		end if
	end repeat
end tell

Note: sed -i is not to be toyed with. In this instance it’s a pretty controlled experiment with dummy files. As with all things UNIX, don’t play if you’re not sure. Seriously.

haha thx all :slight_smile:

Since you mentioned -i: would it be possible to run sed without that flag, capture its output in the AppleScript and then set the record’s plaintext to it?
Something like

set output to do shell script ...
set plain text of thisRecord to output

That of course modifies the record, but at least not the file directly in the database :wink:

Yes, that would also be possible. Just not as sexy… and dangerous :wink:

1 Like

Hi all

i have tried using both the Applescript version and the JS version on my files

using @DTLow excellent and easy to follow Applescript it does delete the

tags:

line it also often cuts also the first title line ,ie the title line below the tags line

tags: 1,2,3
# title 

here is my version of the @DTLow script

tell application id "DNtp"
	set selectedNotes to get selection
	repeat with theNote in selectedNotes
		set newText to my DropLines(plain text of theNote)
		set plain text of theNote to newText
	end repeat
end tell

on DropLines(oldText)
	set savedDelims to AppleScript's text item delimiters
	set AppleScript's text item delimiters to linefeed
	set textLines to text items of oldText
	set AppleScript's text item delimiters to savedDelims
	
	set newText to ""
	repeat with textLine in textLines
		if textLine does not start with "tag" then ------- Criteria for dropping lines   
			set newText to newText & textLine & linefeed
		end if
	end repeat
	return newText
end DropLines

here is in example of a file

tag: #Main, #NorthAfrican, #Chicken, #3

#  Vinegar Chicken With Crushed Olive Dressing

[cooking.nytimes.com](https://cooking.nytimes.com/recipes/1020486-vinegar-chicken-with-crushed-olive-dressing "Vinegar Chicken With Crushed Olive Dressing Recipe - NYT Cooking")

> REVIEW: made it  non ideal conditions. Better make it next time in Dutch over to cook the chicken. Also need to use high quality chicken for this.

after i run the script i get this

[cooking.nytimes.com](https://cooking.nytimes.com/recipes/1020486-vinegar-chicken-with-crushed-olive-dressing "Vinegar Chicken With Crushed Olive Dressing Recipe - NYT Cooking")

> REVIEW: made it  non ideal conditions. Better make it next time in Dutch over to cook the chicken. Also need to use high quality chicken for this.

any clue why? can one force it to just kill the actual first line (that has the tags line)

I also tried using the JS version but i think my regex is really messed up

const app = Application("DEVONthink 3");
const records = app.selectedRecords();
records.forEach(r => {
  let txt = r.plainText();
  r.plainText = txt.replaceAll(/^tag:/g,"");
})

thx again

Z

It is not very helpful if you suddenly change the task. This thread is about deleting “lines by first character”. Now you change the task to (apparently) removing something else altogether.

Since I didn’t write the AppleScript part, I’m not going to comment on this. But in the JS case, you might want to think over what you’re actually asking for. replaceAll will remove all occurences of the regular expression. Not only the first one. Further more, you ask it to remove the string “tag:” wherever it starts a line. If that is what you want, than it’s of course ok. If, as I suppose, you want to remove the whole line starting with “tag:”, you have to add a greedy quantifier that extends to the end of the line.

hi @chrillek

sorry for the confusion, i am actually trying to do exactly that deleting “lines by first character” but rather instead of them starting with < im trying to get rid of lines starting with tags:.

apologize for not being clearer, if you think this warrants a separate post i can open one up.

i tried using regex builder yet for some reason i cant get the hang of matching until the end of the line after it matchers the tags: part.

thx again

Z

Compare your regexp with the one here

The quantifier gobbling everything up to the end of the line is there. Also, I suggest that you read up on regular expressions. That helps a lot more than this kind of recipes.

thx again @chrillek

i looked at @BLUEFROG regex code but that didn’t seem to work

const app = Application("DEVONthink 3");
const records = app.selectedRecords();
records.forEach(r => {
  let txt = r.plainText();
  r.plainText = txt.replaceAll(/^tags.+>$/g,"");
})

@BLUEFROG, any clue on how adjust this?

i will look into regex but TBH my mind is to pathetic to really follow it, Applescript i can deal with regex is for non mortals like me :smiley: :smiley:

thx

Z

This would be looking for lines starting with tags followed by at least one printable character then > and nothing else on the line.

This removes the line starting with tags:

const app = Application("DEVONthink 3");
const rec = app.selectedRecords();
rec.forEach(r => {
  let txt = r.plainText();
  r.plainText = txt.replaceAll(/^tags: .+/g,"");
})

Perfect!

thx so much

Z

No problem.