5

I want to delete lines with number 03,08,13,18,...., 3+5n.

How can I do that? Thank you very much.

yuxuan
  • 781
  • 4
  • 15
  • 1
    You can use `forward-line` and `line-number-at-pos` and `delete-region` -- with `line-beginning-position` and `line-end-position`. – lawlist Dec 07 '15 at 03:58
  • 1
    I wanted to add a comment of a faster method for calculating the line number, which has certain limitations discussed in the comments of the questions/answers of the thread in the following link relating to using `(format-mode-line "%l")`: http://emacs.stackexchange.com/a/3822/2287 What spawned that particular thread, was the need to do 50 calculations of line numbers per command loop, so I needed something faster. – lawlist Dec 07 '15 at 07:03

4 Answers4

8

The Swiss army knife of Emacs is called keyboard macros. See the Emacs Wiki and the manual.

Enter the macro mode, perform the commands of the macro (note: the commands are not only recorded, they are also executed).

Steps:

  • Save your file for backup!
  • Go to line 3 of your file
  • Enter macro recording mode : C-x (
  • Delete this line : M-x kill-whole-line
  • Go down 4 times : down ↓ down ↓ down ↓ down ↓
  • Close the macro : C-x )

In case of any error during this process, you have to cancel the macro recording (C-g), undo until the file is back to the original state (or reload), then create the macro again.

You should now be on line 8.

To repeat the sequence of commands, do C-x e. If you don't do anything else and want to repeat again the macro execution, just enter e, after C-x e was executed.

To repeat the macro 3 times, do C-u 3 C-x e, etc. To repeat the macro until the end of the file is reached (or more generally until an error occurs), do C-u 0 C-x e.

phils
  • 48,657
  • 3
  • 76
  • 115
Déjà vu
  • 143
  • 1
  • 11
3

The following function (briefly tested) will allow you to delete lines with a starting value and a step value:

(defun delete-some-lines (&optional start step)
  "Delete lines starting with START at STEP intervals."
  (interactive)
  (let ((lines (list (or start
                         (string-to-number (read-string "Starting line: ")))))
        (step  (or step (string-to-number (read-string "Skipping: "))))
        (last  (line-number-at-pos (point-max))))
    (while (<= (+ step (car lines)) last)
      (push (+ step (car lines)) lines))
    (save-excursion
      (cl-dolist (line lines)
        (goto-line line)
        (delete-region (point-at-bol)
                       (min (1+ (point-at-eol)) (point-max)))))))

Note that it doesn't do any error checking.

Dan
  • 32,584
  • 6
  • 98
  • 168
1

If the user wishes to also delete the \n at the end of the line, then just change (line-end-position) to (1+ (line-end-position)).

(defun delete-line-number (line)
"Doc-string."
  (save-excursion
    (goto-line line)
    (delete-region (line-beginning-position) (line-end-position))))
lawlist
  • 18,826
  • 5
  • 37
  • 118
0
(defun delete-3+5n-lines ()
  "Delete the 3+5n linum lines in current buffer."
  (interactive)
  (let* ((lines (split-string (buffer-string) "\n"))
         (max-linum (length lines))
         (3+5n-linums
          (cl-loop for x from 0
                   for y = (+ 3 (* 5 x))
                   until (> y max-linum)
                   collect y)))
    (erase-buffer)
    (insert
     (mapconcat
      #'identity
      (cl-loop for x from 1 to max-linum
               unless (memq x 3+5n-linums)
               collect (elt lines (1- x)))
      "\n"))))
xuchunyang
  • 14,302
  • 1
  • 18
  • 39
  • `erase-buffer` -- Are you serious? This approach looks like a machete instead of a scalpel! What if there are overlays? What if there are text properties? What if . . . My comments underneath the question of the original poster basically give the ingredients of what *should be* a valid answer . . . – lawlist Dec 08 '15 at 18:11
  • Yes, since op wants to modify a buffer/file, and also for simplicity (deleting some specific lines in place is difficult). I'm not sure if overlay or test properties make difference. Besides, personally I would like to use bash+sed, not elisp. – xuchunyang Dec 08 '15 at 18:28