From: Tim Landscheidt <tim@tim-landscheidt.de>
To: Skip Montanaro <skip.montanaro@gmail.com>
Cc: help-gnu-emacs@gnu.org
Subject: Re: TIL about string-rectangle
Date: Wed, 30 Dec 2020 21:37:44 +0000 [thread overview]
Message-ID: <87a6tvkmaf.fsf@passepartout.tim-landscheidt.de> (raw)
In-Reply-To: <CANc-5Ux9tXhPFrDt+NX6YtCjHLOrkbAXixoRL6XzhBJLdqcXiQ@mail.gmail.com> (Skip Montanaro's message of "Wed, 30 Dec 2020 14:59:25 -0600")
Skip Montanaro <skip.montanaro@gmail.com> wrote:
> I needed to replace the first comma on each line of a CSV file so I
> could more conveniently sort by the first field (date, arranged as
> MM/DD/YYYY). After a bit of fussing around, I got it squared away with
> query-replace-regexp, did my sort, then needed to revert the
> replacement text back to comma. Unfortunately, there were a few other
> instances of the replacement text elsewhere in the file which caused
> problems. (If I'd had my thinking cap on I would have checked before
> doing the original replace, but it seems I was wearing my dunce
> cap...) Poking around for help from Emacs against a future need, I
> discovered replace-rectangle, which turns out to be an alias for
> string-rectangle (bound to C-x r t). It looks to be quite handy when
> you need to replace text within a rectangle. It's sort of (but not
> quite) like narrow-to-region + query-replace(-regexp)?. It doesn't
> query for a string to replace. It simply replaces the rectangle's
> contents with the given string on each line.
For complex sorts, I once wrote a function that enhances
sort-regexp-fields (and needs a docstring and comments that
I could understand after eight years):
| (defun tl-sort-regexp-fields (reverse record-regexp key-regexp beg end)
| "Extended sort function."
| (interactive "P\nsRegexp specifying records to sort: \nsRegexp specifying key within record: \nr")
| (if (string-match "\\`\\(?:-\\\\[1-9]\\|\\(?:-?\\\\[1-9]\\)\\{2,\\}\\)\\'" key-regexp)
| (let
| ((i (length key-regexp)))
| (while (> i 0)
| (let ((key-reverse (and (> i 2) (= (aref key-regexp (- i 3)) ?-)))
| (key (substring key-regexp (- i 2) i)))
| (sort-regexp-fields (if reverse (not key-reverse) key-reverse) record-regexp key beg end)
| (if key-reverse
| (setq i (- i 1)))
| (setq i (- i 2)))))
| (sort-regexp-fields reverse record-regexp key-regexp beg end)))
Basically, you can select a region of a CSV file, then enter
(untested)
"^,\([0-9][0-9]\)/\([0-9][0-9]\)/\([0-9][0-9][0-9][0-9]\),.*$"
at the first prompt and "\3\1\2" at the (incorrectly named)
second, and then the lines would be sorted by year, month,
day. You can reverse the order for individual keys by pre-
pending a "-". It takes advantage of the (not guaranteed?)
fact that Emacs's sort functions are stable, i. e. the order
of lines with the same key is not changed.
If someone wants to clean that up and include it either as a
separate function in Emacs or semi-backwards-compatibly in
sort-regexp-fields, much appreciated.
Tim
next prev parent reply other threads:[~2020-12-30 21:37 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-30 20:59 TIL about string-rectangle Skip Montanaro
2020-12-30 21:37 ` Tim Landscheidt [this message]
2020-12-30 22:11 ` Skip Montanaro
2020-12-31 8:03 ` Yuri Khan
2020-12-31 10:21 ` Emanuel Berg via Users list for the GNU Emacs text editor
2020-12-31 12:44 ` Skip Montanaro
2020-12-31 14:32 ` Tim Landscheidt
2020-12-30 21:43 ` Drew Adams
2020-12-30 22:08 ` Skip Montanaro
2020-12-30 23:11 ` Drew Adams
2020-12-30 23:23 ` Drew Adams
2020-12-30 23:24 ` Skip Montanaro
2020-12-31 7:15 ` Sivaram Neelakantan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87a6tvkmaf.fsf@passepartout.tim-landscheidt.de \
--to=tim@tim-landscheidt.de \
--cc=help-gnu-emacs@gnu.org \
--cc=skip.montanaro@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).