0

I have a file, and I want to search if a given file has a string.

I want to call that function from an elisp function.

AFAIK, all the grep family of functions open a new buffer. I only need to know if a string is present or not in the file.

Thanks in advance

2
  • Please take a look at the answer and let me know if it resolves your problem. Thanks! Commented Jun 28, 2024 at 17:34
  • Hello NicK! I added the approach I ended up using. Thank you so much for all your help! Commented Jun 28, 2024 at 18:03

2 Answers 2

1

Easiest is to invoke the external grep program using shell-command:

 (defun my/grep-p (search-string file)
   (= 0 (shell-command (format "grep -s -q \'%s\' \"%s\"" search-string file))

grep -s -q is silent and only returns status: 0 if found, 1 if not found, 2 if there is an error. So the function acts as a predicate: it returns t if the string is found in the file, nil otherwise. The function adds single quotes around the search pattern to protect it from globbing and other such shell transformations and double quotes around the file name to protect it in case it contains spaces: that's not complete protection but it will take care of most cases.

This function can be used in Lisp programs, but not interactively. Interactively, I would just call shell-command with M-! and give it the command grep -s -q <pattern> <file> explicitly, then check the status in the echo area.

1

Instead of using grep; I ended going with a "OS agnostic" approach.

I use Emacs' string-match function in conjunction with f-read-text to obtain a very close approximation to grep.

So to recreate:

grep hello file

I did the following:

(string-match "hello" (f-read-text file)) 

I am not aware of the speed differences between @NickD's approach using an external shell and this one. This one seemed "simpler" to me at least.

If anyone else is looking for a function, here's what I used:

(defun my/grep-p (search-string file)
  (let (
        (fileContent (f-read-text file))
        )
    (string-match search-string fileContent)
    )
  )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.