버퍼에서 각 라인을 읽어 한 줄씩 처리하는 관용적 방법이 있습니까?


11

파이썬에서는 파일을 한 줄씩 처리하기 위해 다음을 수행합니다.

with open(infile) as f:
    for line in f:
        process(line)

elisp (파일 대신 버퍼 사용)에서 동일한 작업을 수행하는 방법을 찾으려고 노력하면서 명확한 방법을 찾지 못했습니다.

(내가 끝내고 싶은 것은 정규식과 일치하는 모든 줄과 일치하지 않는 것을 포함하는 두 줄의 데이터 구조입니다.)

답변:


23

여러 가지 방법이 있습니다. 다음과 같이 Kaushal의 방법을 좀 더 효율적으로 만들 수 있습니다.

(goto-char (point-min))
(while (not (eobp))
  (let ((line (buffer-substring (point)
                                (progn (forward-line 1) (point)))))
    ...))

그러나 Emacs에서는 문자열보다는 버퍼에서 작업하는 것이 훨씬 관례입니다. 따라서 문자열을 추출하고 작업하는 대신 다음을 수행하십시오.

(goto-char (point-min))
(while (not (eobp))
  ...
  (forward-line 1))

또한 전체 버퍼가 아닌 영역에서 작업하고 싶거나 "operate"에 버퍼 수정이 포함되어 있으면 뒤로 수행하는 경우가 자주 있습니다 (따라서 "end" "버퍼를 수정할 때마다 지역의 위치가 이동합니다) :

(goto-char end)
(while (> (point) start)
  ...
  (forward-line -1))

최적화 팁에 감사드립니다! 항상 배우는 것이 좋습니다.
Kaushal Modi

마지막 스 니펫 정보는 다음과 같아야합니다 (let ((start (point))) (goto-char (point-max)) (while (> (point) start) ... (forward-line -1))).
Kaushal Modi

아니, 마지막 조각은 그냥 가정 start하고 end사업을 영위하고자하는 지역을 구분하는 변수를 기존 있습니다.
Stefan

6

나는 관용적 인 방법을 모르지만 이것을 생각해 냈습니다.

(defun my/walk-line-by-line ()
  "Process each line in the buffer one by one."
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (not (eobp))
      (let* ((lb (line-beginning-position))
             (le (line-end-position))
             (ln (buffer-substring-no-properties lb le)))
        (message ">> %s" ln) ; Replace this with any processing function you like
        (forward-line 1)))))

1

나는 다음과 같은 것이 관용적이라고 생각한다.

(dolist (line (split-string (buffer-string) "\n")) 
  ... process line here ...
  )

편집 : 여기에 다른 솔루션이 loop있으며 dolist정규 표현식과 일치하는지 여부에 따라 행을 분류합니다.

(loop for line in (split-string (buffer-string) "\n")
  if (string-match "your-regexp" line)
    collect line into matching
  else
    collect line into nonmatching
  finally return (cons matching nonmatching)
  )

이 함수의 출력에 변수를 설정하면 (예 (setq x (loop ...)): 일치 (car x)하지 않는 행 목록 이있는)에 일치하는 행 목록이 표시 (cdr x)됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.