5

假设我有一个配置文件,每一行都包含空格分隔的值。在列上,我只有零。例子:

... # there is more configuration before the interesting stuff:
0 0 file /dev/stdin 224.0.68.54:12131
0 0 file /dev/stdin 224.0.68.55:12102
0 0 file /dev/stdin 224.0.68.49:12333
0 0 file /dev/stdin 224.0.68.60:12184
0 0 file /dev/stdin 224.0.68.62:12888
0 0 file /dev/stdin 224.0.68.77:12001
0 0 file /dev/stdin 224.0.68.33:12973

现在我想用它的索引增加第二列。那就是我想要这个结果:

0 0 file /dev/stdin 224.0.68.54:12131
0 1 file /dev/stdin 224.0.68.55:12102
0 2 file /dev/stdin 224.0.68.49:12333
0 3 file /dev/stdin 224.0.68.60:12184
0 4 file /dev/stdin 224.0.68.62:12888
0 5 file /dev/stdin 224.0.68.77:12001
0 6 file /dev/stdin 224.0.68.33:12973

如何在emacs lisp中做到这一点?或者任何其他的 Emacsen 做事方式?

4

6 回答 6

10

您可以使用评估表达式搜索和替换的可能性:

  • 将点放在要处理的第一行
  • M-x查询替换正则表达式RET
  • 搜索字符串:^0 \([0-9]+\)
  • 用。。。来代替:\,(format "0 %s" (+ \#1 \#))

意思是:

  • 在行首搜索前面有单个零的数字
  • 替换为评估结果,其中\#1是第一个匹配组(如 \1 但转换为数字),并且\#是已经完成的替换次数(第一次替换从 0 开始)。表达式会针对每个匹配进行评估。

如果第一个数字不总是零,我会使用:

  • 搜索字符串:^\([0-9]+\) \([0-9]+\)
  • 用。。。来代替:\,(format "%s %s" \#1 (+ \#2 \#))
于 2013-06-04T15:39:00.903 回答
7

您可以使用带有计数器的宏来执行此操作。您开始使用 定义宏,F3并使用 结束定义F4。在定义宏时,F3再次点击将插入计数器的值并增加它。定义宏后,点击 运行它F4

因此,在您的情况下,将点移动到第一个有趣行的开头,点击F3 C-f C-f C-d F3 C-n C-a F4(即删除第二个零,插入计数器,然后移动到下一行的开头)。然后F4根据需要多次点击以更改所有行。

如果需要更改计数器的值,请使用M-x kmacro-set-counter.

于 2013-06-04T15:07:58.193 回答
6

与 Jonathan Leech-Pepin 的回答类似,您也可以使用非 cua 矩形编辑命令(尽管分两步而不是一步)。

  • 设置标记并指向列矩形的角
  • C-xrk删除矩形。
  • C-uC-xrN在其位置插入一个数字序列。

另请参阅相关问题:
emacs string-insert-rectangle vector of numbers?

于 2013-06-05T23:55:45.883 回答
4

您可以使用的东西org-mode(我不确定您将如何使用结果,但这可能是一种方法)

| N | X | file | stream     |                ip |
|---+---+------+------------+-------------------|
| 0 | 0 | file | /dev/stdin | 224.0.68.54:12131 |
| 0 | 1 | file | /dev/stdin | 224.0.68.55:12102 |
| 0 | 2 | file | /dev/stdin | 224.0.68.49:12333 |
| 0 | 3 | file | /dev/stdin | 224.0.68.60:12184 |
| 0 | 4 | file | /dev/stdin | 224.0.68.62:12888 |
| 0 | 5 | file | /dev/stdin | 224.0.68.77:12001 |
| 0 | 6 | file | /dev/stdin | 224.0.68.33:12973 |
#+TBLFM: $2=@#-2

一些解释,或者更确切地说,如何获取原始数据并将其转换为此表:

  • 将您的数据复制到文件 config.org

  • 通过基本的字符串替换命令创建表。(只需复制您现在拥有的文本,选择所有文本,然后C-c |

  • #+TBLFM:部分是该表的“公式”,它的含义如下:为第二列中的每个单元格分配其行的序号减 2(它们从 1 开始计数行,并且该表有一个标题行)。

  • 每当您C-c C-c使用公式时,它都会将其重新应用于表格(因此您可以在修改文档时附加更多行,重新应用公式将自动更新表格。)

于 2013-06-04T16:48:37.590 回答
2

您可以使用cua-set-rectangle-mark.

评估:

(cua-mode 't)

然后在缓冲区中,您可以M-x cua-set-rectangle-mark在第二列使用,然后将矩形向下延伸到列表的末尾。

然后使用M-n(sequence)、 的默认值,Start (0):所有这些都提供了您在这种情况下需要的内容。Increment (1):Format (%d):

于 2013-06-05T13:48:23.947 回答
0

这是一种非常简单的方法(使用与Seki 的答案相同的技术,但更容易):

选择您希望增量出现的所有行,然后发出

M-x replace-regexp "^0 0" "0 \#"

或更详细地说:

  • M-x replace-regexp RET
  • 搜索到的字符串:^0 0
  • 用。。。来代替:0 \#

这将为您提供所需的结果,因为\#将替换完成的替换次数。

于 2019-05-18T07:27:16.597 回答