help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: file filtering


From: Kevin Rodgers
Subject: Re: file filtering
Date: Wed, 31 Jan 2007 22:55:44 -0700
User-agent: Thunderbird 1.5.0.9 (Macintosh/20061207)

Peter Tury wrote:
I would like to write an emacs lisp script what (filters +) modifies a
file logically in the following way:

* processes the file content line by line

* if line corresponds to a given regexp, then replaces the line by
  something built up from found regexp-parts (\1...)

* otherwise deletes the line

I would like to use this script similarly to grep: so emacs would run
in the backgroup (using --script initial option at Emacs invocation).

(find-file FILENAME)
(shell-command-on-region (point-min) (point-max)
                         (format "sed -n s/%s/%s/p"
                                 (shell-quote-argument REGULAR_EXPRESSION)
                                 (shell-quote-argument REPLACEMENT))
                         nil t)
(save-buffer) ; or (write-file NEW_FILENAME)

For this I am looking for some functionalities/functions what I don't
know:

* how to read a file without loading the whole file into memory
  (i.e. e.g. without loading it into a buffer)

E.g. I thought of a solution when I would read from the file only
strings what correspond to a given regexp. Something like
(insert-file-contents filename regexp). (In the "simpliest" case
regexp would be "^.*$".) Is this possible?

(shell-command (format "grep %s %s"
                        (shell-quote-argument FILENAME)
                        (shell-quote-argument REGULAR_EXPRESSION))
                t)

Then, the second step would be to replace the just inserted text, so
something like the following would be even better
(insert-file-contents filename regexp replace-match-first-arg): this
would find the regexp in filename, replace the found string according
to replace-match (in memory) and insert only the result into the buffer.

(replace-regexp REGEXP TO-STRING nil (point-min) (point-max))

Then (after a while loop what processes the whole file), the third
step would be to write the result into a new file, so the best would
be something like this :-) (append-to-file to-filename from-filename
regexp-to-read replace-match-first-arg-to-append)

(write-file NEW_FILENAME)

I think I could create these functions if I would know how to read a
portion (not fixed number of chars!) of a file...

Use an external command like grep to select the desired lines.  But
since you need to do that, you may as well use an external command like
sed to do the whole replacement -- otherwise, you're matching the
regular expression twice, once outside emacs to select the lines to
insert into the buffer and once inside emacs to find the text to
replace.

My problem is this: if I work on buffers (instead of files), I have to
create two buffers: one that corresponds to the original file and one
that corresponds to the result file -- or otherwise I have to delete
those portions of the first buffer what didn't matched by the regexp
searches -- and I don't know how to do it simply :-( Or using two
buffers (strings??) (and storing the two files in them) for such a
task isn't an ugly solution?

How to solve this task in the simpliest way?

(with-temp-file NEW_FILENAME
  (shell-command (format "sed -n s/%s/%s/p %s"
                         (shell-quote-argument REGULAR_EXPRESSION)
                         (shell-quote-argument REPLACEMENT)
                         (shell-quote-argument FILENAME))
                 t                     ; output-buffer: (current-buffer)
                 nil))

--
Kevin Rodgers
Denver, Colorado, USA





reply via email to

[Prev in Thread] Current Thread [Next in Thread]