Executing Preview from a command line and use the find instruction

I have PDF documents that I want to display with Preview and find a string inside. I can use a script command like this to display the file:


osascript -e 'tell application "Preview"' -e'activate' -e 'open POSIX file "/Users/me/Downloads/something.pdf"' -e ' end tell'


But I don't know how to add the Find command to highlight some words in the displayed PDF.


Can someone please give me an advice?


Thank you all!

MacBook Pro 13″, macOS 14.2

Posted on Dec 21, 2023 8:03 AM

Reply
Question marked as Top-ranking reply

Posted on Dec 21, 2023 9:55 AM

Thank you, MrHoffman,


Is the PDF display a necessary part of this?

Yes, it is.

Spotlight can query a PDF file

Can I call spotlight from the command line or a script?

On the AppleScript-based path you’re presently on, here’s an earlier discussion:
Applescript to find a text string in a PDF - Apple Community

That's not what I need in this case.


Meanwhile I found a solution:


osascript \
-e 'tell application "System Events"' \
-e 'tell application "Preview"' \
-e 'activate' \
-e 'open "/Users/me/Downloads/something.pdf"' \
-e 'end tell' \
-e 'delay 0.2' \
-e 'keystroke "f" using command down' \
-e 'delay 0.05' \
-e 'keystroke "Aktien"' \
-e 'key code 36' \
-e 'end tell'


Thank you again!

Similar questions

17 replies
Question marked as Top-ranking reply

Dec 21, 2023 9:55 AM in response to MrHoffman

Thank you, MrHoffman,


Is the PDF display a necessary part of this?

Yes, it is.

Spotlight can query a PDF file

Can I call spotlight from the command line or a script?

On the AppleScript-based path you’re presently on, here’s an earlier discussion:
Applescript to find a text string in a PDF - Apple Community

That's not what I need in this case.


Meanwhile I found a solution:


osascript \
-e 'tell application "System Events"' \
-e 'tell application "Preview"' \
-e 'activate' \
-e 'open "/Users/me/Downloads/something.pdf"' \
-e 'end tell' \
-e 'delay 0.2' \
-e 'keystroke "f" using command down' \
-e 'delay 0.05' \
-e 'keystroke "Aktien"' \
-e 'key code 36' \
-e 'end tell'


Thank you again!

Dec 21, 2023 2:26 PM in response to Thommy_

Thommy_ wrote:

@MrHoffmann: Thank you. But Spotlight only finds metadata. I need them in the text itself.


Spotlight indexes both data and metadata.


If you couldn’t query for text located within a file, then Spotlight wouldn’t be all that useful, no?


The limitation here being how fast the data can get indexed and added to the index, assuming a very-recently-arrived file. That indexing can be encouraged with the mdimport command, and the mdls command can be useful for seeing what metadata (as differentiated from data) is collected for a particular file.


General syntax:

mdfind -onlyin /path/to/file “query”


In this case, look at kMDItemTextContent possibly combined with other keywords for the text content.


Dec 22, 2023 7:05 AM in response to Thommy_

Syntax is king.


I have some PDFs on my Desktop and a few of these contain the same text content. I want to see which PDFs contain the case-insensitive word "graecis." The only modifiers supported are c for case-insensitive and d for insensitive to diacritical marks. There is no w modifier.


odin: ~/Desktop % mdfind -onlyin ~/Desktop 'kMDItemTextContent == "graecis"cd' *.pdf
/Users/viking/Desktop/test.pdf
/Users/viking/Desktop/test_pdfx3.pdf
/Users/viking/Desktop/text_svg_13_1.pages
odin: ~/Desktop %



If I have changed "graecis" to "*aeci*", I would have obtained the same result.

Dec 22, 2023 12:44 AM in response to Thommy_

I have to correct myself. Of course Spotlight also indexes the content of the files. I have already solved the problem with Preview. But I also wanted to use mdfind to determine in which PDF files the search criterion is located. I encountered 3 problems:


  • I can't exclude subdirectories.
  • I cannot limit the search to PDF files.
  • I cannot use search criteria that contain spaces. The search always finds the locations for each individual word.


To test this, I tried the following commands, for example:


mdfind -onlyin . 'kMDItemTextContent == *where is* cdw'
mdfind -onlyin *.pdf 'kMDItemTextContent == *where is* cdw'
mdfind -onlyin . -name *.pdf 'kMDItemTextContent == *where is* cdw'


None of these lead to the desired result. Only the first one is executed without error. But it contains all file types, searches through all subdirectories and treats where is as single words. Using quotation marks does not help either.

Dec 22, 2023 8:11 AM in response to Thommy_

I just tested that syntax on my macOS Sonoma 14.2.1 installation and it works just like it has for several releases of macOS before it. When you use -onlyin ".", mdfind will be recursive below that filesystem location, and *.pdf would restrict it to only that file type. That is why I expressly limited the scope to my Desktop.


Use my syntax exactly as shown and be specific about the -onlyin argument.


The File Metadata programming guide only offers c and d as modifiers. Nothing there about w, even though the mdfind(1) man page shows an example for -interpret that uses an undocumented w modifier in how Spotlight tool would form the search — except you are on the command line and I never use the -interpret switch.


If you are passing this mdfind against PDFs that were scanned, and not OCRd, they are PDF wrappers around an image and the kMDItemTextContent cannot match text against an image.

Dec 22, 2023 8:44 AM in response to VikingOSX

Thank you! I did use the syntax exactly as you mentioned and this is the result:


Thomas'MBP:Downloads entwicklung$ mdfind -onlyin ~/Downloads 'kMDItemTextContent == "Hannover" cd' *.pdf
/Users/entwicklung/Downloads/Billi/BilliProjekt/Resources/Tarife & Provider/WWW/Telefongesellschaften -- Telcos.htm
/Users/entwicklung/Downloads/Billi/Werbung/Adressen Computerzeitschriten.doc
/Users/entwicklung/Downloads/Billi/Werbung/Adressen Handyzeitschriften.doc
/Users/entwicklung/Downloads/Billi/CBProjekt/Resources/Tarife & Provider/WWW/Telefongesellschaften -- Telcos.htm
/Users/entwicklung/Downloads/aktienbrief567.pdf
/Users/entwicklung/Downloads/aktienbrief549.pdf
Thomas'MBP:Downloads entwicklung$ 


It finds the string Hannover in .pdf, .doc and .htm files and in subdirectories, too.


Any idea what I'm doing wrong?


VikingOSX wrote:

If you are passing this mdfind against PDFs that were scanned, and not OCRd, they are PDF wrappers around an image and the kMDItemTextContent cannot match text against an image.

That's ok. I know this.


Trying the same with another shell (zsh) I get these results:


entwicklung@Thomas'MBP / % mdfind -onlyin ~/Downloads 'kMDItemTextContent == "Hannover" cd' *.pdf
zsh: no matches found: *.pdf
entwicklung@Thomas'MBP / % 


When I use the command


entwicklung@Thomas'MBP / % mdfind -onlyin ~/Downloads 'kMDItemTextContent == "Hannover" cd'


I get the same result as with bash.


I use Sonoma 14.2.1 on a MBP M1 13" and on an iMac Intel 27" with the same results.


Dec 22, 2023 8:53 AM in response to Thommy_

I see what you mean now trying my own ~/Downloads folder. The following restricts your results to PDF. Remember the c modifier allows for case-insensitive searches which is why hannover appears below. Remember, it is recursive, so it will drill into sub-folders…


mdfind -onlyin ~/Downloads 'kMDItemTextContent == "hannover"cd' * | grep pdf


or:


mdfind -onlyin ~/Downloads 'kMDItemKind == "*pdf*"cd && kMDItemTextContent == "hannover"cd' *


Dec 22, 2023 10:52 AM in response to Thommy_

And if you do not want recursion, there is the AppleScript approach that you can copy/paste into Apple's Script Editor… 🧐 and run.


use framework "Cocoa"
use AppleScript version "2.4" -- Yosemite or later
use scripting additions

property NSString : a reference to current application's NSString
property NSWorkspace : a reference to current application's NSWorkspace
property NSURL : a reference to current application's NSURL

set query to "kind:pdf AND \"Hannover\""

set thisFolder to POSIX path of (choose folder) as text
set basefolder to ((NSString's stringWithString:thisFolder)'s lastPathComponent()) as text
(NSWorkspace's sharedWorkspace)'s openURL:(NSURL's fileURLWithPath:thisFolder)
set result_code to (NSWorkspace's sharedWorkspace)'s showSearchResultsForQueryString:query
-- close the opened folder but not the search results folder
tell application "Finder" to close Finder window basefolder
return




This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Executing Preview from a command line and use the find instruction

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.