Script: Auto group by name pattern

Hi there,

this script groups selected records on a pattern you specified, in my case it was YYYY-MM-DD at the name beginning. It saves the user from selecting records that share e.g. the same name beginning manually, meaning that you don’t have to select records “one pattern by one”. Just select all records and run it.

It’s the normal DEVONthink 3 behaviour when grouping records, but without the manually selecting

-- Auto group by name pattern (in this case a YYYY-MM-DD date at the beginning)

tell application id "DNtp"
	try
		set windowClass to class of window 1
		if {viewer window, search window} contains windowClass then
			set currentRecord_s to selection of window 1
		else if windowClass = document window then
			set currentRecord_s to content record of window 1 as list
		end if
		
		repeat with thisRecord in currentRecord_s
			set theName to name of thisRecord
			set thePattern to characters 1 thru 10 in theName as string -- date as YYYY-MM-DD
			set theGroup to create location (location of current group) & "/" & (name of current group) & "/" & thePattern & "/" in current database
			move record thisRecord to theGroup
		end repeat
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell

Which version of DEVONthink do you use? Version 3 recognizes common prefixes/suffixes/words and uses them for the group’s default name.

Hi, I’m using 3.0.1 but that’s all fine. Only used this script to “auto group” by a given pattern (to bypass the manual selection of records that I want DEVONthink 3 to built its pattern from). See the two captures

1

Using DEVONthink 3’s built-in feature results in

2

But what I needed was only 2019-11-02 so that’s what this script is for.
DEVONthink 3’s own feature is great, I like it a lot, this was just a “special case” I had to do once (but on many records) :slight_smile:

In case you’re trying to run the script I posted in this thread you’ll find that it doesn’t work in DEVONthink 3.6. That’s due to DEVONthink’s new handling of “invalide arguments”.

After the release of DEVONthink 3 I decided to continue to use “search window” in scripts so that DEVONthink 2 users could use them in, well, search windows. With version 3.6 that’s not possible anymore.

If you want to use the script you’ll have to replace this voluminous block …

set windowClass to class of window 1
if {viewer window, search window} contains windowClass then
	set currentRecord_s to selection of window 1
else if windowClass = document window then
	set currentRecord_s to content record of window 1 as list
end if

… with this neat line …

set currentRecord_s to selected records

… which does what the six lines have done. Wow, that’s great! :smiley:

“Just select all records and run it.”

“but without the manually selecting”

:thinking:

Does this script groups all files if the have the same name? No matter where the files are saved, created or imported?

No, it groups records in the current group depending on the pattern you specify in the script. If necessary it creates new groups in the current group.

This is what happens with the pattern characters 1 thru 10 in theName:

  1. Select all records you want to group with the given pattern

1

  1. Result

2

The advantages to DEVONthink’s built in grouping behaviour are:

  • You don’t have to select each pattern manually.
  • You can group selected records into an existing group.
  • You can specify the pattern.

With the script it’s a 2 step process:

  • Select the records
  • Run the script

With DEVONthink’s built in grouping it would have been:

  • Select all records that start with “2020-11-27”
  • Use menu Data > Group Items
  • Rename the new group to “2020-11-27”, as DEVONthink uses the longest string that all records start with, in this case “2020-11-27 - Test”.
  • Select all records that start with “2020-11-28”
  • Use menu Data > Group Items
  • Rename the new group to “2020-11-28”.
  • Select all records that start with “ABCDEFGHIJ”
  • Use menu Data > Group Items
  • Rename the new group to “ABCDEFGHIJ”.

See the difference?

yes, much easier.

I tend to save, import or create items that start with XYZ all over the place(any database)
Can this script be used to gather items with XYZ that are save, imported or saved in any database then group them?

No :weary:

Did you actually read the explanation I posted yesterday? :face_with_monocle:

This one searches across all databases and moves the results to a group.

-- Search across databases and move results to group

set theNameStart to "XYZ"
set theDatabaseName to "_temp"

tell application id "DNtp"
	try
		set theResults to search ("name:<" & theNameStart & space & "kind:any") as string
		
		if theResults ≠ {} then
			try
				set theDatabase to database named theDatabaseName
			on error
				error ("Please open database \"" & theDatabaseName & "\"") as string
			end try
			
			set theGroup_Name to theNameStart
			set theGroup to create location "/" & my replace_String(theGroup_Name, "/", "\\/") in theDatabase
			
			repeat with thisRecord in theResults
				move record thisRecord to theGroup
			end repeat
		end if
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
		return
	end try
end tell

on replace_String(theText, oldString, newString)
	local ASTID, theText, oldString, newString, lst
	set ASTID to AppleScript's text item delimiters
	try
		considering case
			set AppleScript's text item delimiters to oldString
			set lst to every text item of theText
			set AppleScript's text item delimiters to newString
			set theText to lst as string
		end considering
		set AppleScript's text item delimiters to ASTID
		return theText
	on error eMsg number eNum
		set AppleScript's text item delimiters to ASTID
		error "Can't replaceString: " & eMsg number eNum
	end try
end replace_String

Thank you, will give this a try.

Is there a way I can use this to group items by names of varying character length (not case-sensitive)?

What you need is to change the hard coded value 10 in this line:

set thePattern to characters 1 thru 10 in theName as string

You could either do this by hard coding the values you need and saving different script versions.

Or you could add a choose from list dialog whose result you can use instead of the hard coded value.

Or you could add a display dialog dialog whose result you can use instead of the hard coded value. This is the most flexible way because you could use the script with any name length.


The thread title and script name are actually misleading. All that the script does is getting a specified range of a record‘s name and creating a group from that. There’s no actual recognition of any pattern done.

Thank you, I understood the approach. In my case, I have items of varying length. So when I tried 1-20, the script gave an error for short items. If I try 1-10, it cuts of the long items from the group name. The list or display dialog is ok if I have a few items. I am trying to group emails imported into DT, where I did not use the group by item option when I imported them.