简体   繁体   English

如何自动修改代码?

[英]How to automate the modification of code?

I have a large piece of code consisting of thousands of equations.我有一大段代码,由数千个方程组成。 Example of two connective lines, corresponding to lines 998 and 999 is对应于第 998 和 999 行的两条连接线的示例是

sum(x[i]*y[i]for i in 1:n) == 15;
sum(z[i]*x[i]for i in 1:n) == 30;

I would like to replace such lines with the following我想用以下内容替换这些行

sum(x[i]*y[i]for i in 1:n) - 15 >= -s[998];
sum(x[i]*y[i]for i in 1:n) - 15 <=  s[998];

sum(z[i]*x[i]for i in 1:n) - 30 >= -s[999];
sum(z[i]*x[i]for i in 1:n) - 30 <=  s[999];

How to automate this process?如何自动化这个过程?

Substitutions换人

Our first step is to transform each individual line:我们的第一步是转换每一行:

sum(x[i]*y[i]for i in 1:n) == 15;

into this:进入这个:

sum(x[i]*y[i]for i in 1:n) - 15 >= -s[998];

While doing it in one command would be a nice parlor trick, we will do it in several easier to follow steps.虽然在一个命令中执行此操作将是一个不错的客厅技巧,但我们将通过几个更容易遵循的步骤来执行此操作。

  1. == to - ==-

    Here is our first command, it is very simple:这是我们的第一个命令,非常简单:

     :%s/==/-<CR>
    • : enters command-line mode. :进入命令行模式。
    • % is the range of lines on which to execute the following command. %是执行以下命令的行范围。 Here, % is a shortcut for 1,$ (from line 1 to last line), thus "every line".这里, %1,$的快捷方式(从第 1 行到最后一行),因此是“每一行”。
    • s is the "substitute" command, see :help :s . s是“替代”命令,参见:help :s
    • /== is what you want to substitute. /==是您要替换的内容。
    • /- is what you want to substitute it with. /-是您要替换它的内容。
    • Press <CR> (ENTER) to execute the command.<CR> (ENTER) 执行命令。

    In plain english: "substitute every == with - ".用简单的英语:“将每个==替换为- ”。

    We should get something like:我们应该得到类似的东西:

     sum(x[i]*y[i]for i in 1:n) - 15; sum(z[i]*x[i]for i in 1:n) - 30;
  2. ; to >= -s[XXX];>= -s[XXX];

    Here is our second command:这是我们的第二个命令:

     :%s/;/ >= -s[XXX];

    Where we substitute every ;我们替换每个; with a generic >= -s[XXX];使用通用>= -s[XXX]; . . This is also quite simple.这也很简单。

    In plain english: "substitute every ; with >= -s[XXX]; .用简单的英语:“用>= -s[XXX]; ;

    We should get something like:我们应该得到类似的东西:

     sum(x[i]*y[i]for i in 1:n) - 15 >= -s[XXX]; sum(z[i]*x[i]for i in 1:n) - 30 >= -s[XXX];
  3. XXX to line number XXX到行号

    Here is our third command:这是我们的第三个命令:

     :%s/XXX/\=line('.')

    The big change between this command and the other ones is that the replacement part is dynamic.此命令与其他命令之间的最大变化是替换部分是动态的。 With \= , we use an expression that is evaluated during each execution instead of a fixed string.使用\= ,我们使用在每次执行期间评估的表达式而不是固定字符串。 line('.') is a vimscript function that returns a line number, which is exactly what we want between those brackets. line('.')是一个 vimscript 函数,它返回一个行号,这正是我们想要的括号之间的内容。

    In plain english: "substitute every XXX with the current line number".用简单的英语:“用当前行号替换每个XXX ”。

    We should get something like:我们应该得到类似的东西:

     sum(x[i]*y[i]for i in 1:n) - 15 >= -s[998]; sum(z[i]*x[i]for i in 1:n) - 30 >= -s[999];

Duplication复制

Here we duplicate each line with a single command:在这里,我们用一个命令复制每一行:

:g/^/t.|s/-s/ s
  • :g is the :help :global command. :g:help :global命令。
  • /^/ matches every line so the following command will be executed on every line. /^/匹配每一行,因此将在每一行上执行以下命令。
  • t is the :help :t command. t:help :t命令。
  • . represents the current line.表示当前行。
  • | separates two commands.分隔两个命令。
  • s/-s/ s removes the - before the s on the duplicated line. s/-s/ s删除重复行上s之前的-

In plain english: "mark every line, then copy each marked line below itself, then remove that leading - before the s ".用简单的英语:“标记每一行,然后复制其自身下方的每个标记行,然后删除该前导-s之前”。

We should get something like:我们应该得到类似的东西:

sum(x[i]*y[i]for i in 1:n) - 15 >= -s[998];
sum(x[i]*y[i]for i in 1:n) - 15 >=  s[998];
sum(z[i]*x[i]for i in 1:n) - 30 >= -s[999];
sum(z[i]*x[i]for i in 1:n) - 30 >=  s[999];

One last thing最后一件事

We use one last command to add a line between our blocks:我们使用最后一个命令在块之间添加一行:

:g/ s[/put=''
  • Every line matching s[ is marked.s[匹配的每一行都被标记。
  • We use :help :put to append an empty line.我们使用:help :put追加一个空行。

In plain english: "put an empty line after each line with s[ ".用简单的英语:“用s[ ”在每一行之后放置一个空行。

We should get something like:我们应该得到类似的东西:

sum(x[i]*y[i]for i in 1:n) - 15 >= -s[998];
sum(x[i]*y[i]for i in 1:n) - 15 >=  s[998];

sum(z[i]*x[i]for i in 1:n) - 30 >= -s[999];
sum(z[i]*x[i]for i in 1:n) - 30 >=  s[999];

What did we learn?我们学到了什么?

  • how to perform simple substitutions with :help :substitute ,如何使用:help :substitute执行简单的替换,
  • the notion of :help :range , :help :range的概念,
  • how to use an expression in the replacement part (the usual gateway drug to vimscript) with :help sub-replace-\= ,如何通过:help sub-replace-\=在替换部分(vimscript 的常用网关药物)中使用表达式,
  • how to execute arbitrary commands on lines matching a specific pattern with :help :global ,如何使用:help :global在与特定模式匹配的行上执行任意命令,
  • how to copy a given line to a given address with :help :t ,如何使用:help :t将给定行复制到给定地址,
  • how to put some text, here an empty string, below the current line with :help :put ,如何使用:help :put在当前行下方放置一些文本,这里是一个空字符串,
  • how to separate commands with :help :|如何使用:help :|分隔命令. .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM