回到首页

拆解remplace代码

Date:2021-5-30

Author:Sid


引言

5月25日的课上,老师使用的ORCHIDEE自动化脚本中出现了emplace()函数,这个函数到底做了什么?遵循了什么语法?在这里分析一下。以及是否有其他。

首先是老师的代码

涉及的基础知识有:

开始之前需要知道:

  1. 本文代码中每行开头的$来表示命令提示符,表示后面的内容需要在命令行环境下输入。开头没有$表示这行内容是shell脚本中的代码。#开始为注释。
  2. 本文中<something>用尖括号表示的部分是命令中需要替换的部分,连尖括号一起换成想要输入的内容。
  3. 本文中按照示例输入后,需要回车,命令才会执行。
  4. 输入命令和编写shell的时候要注意是否有空格。

Shell的变量

$1$2分别是传入函数的第一个和第二个变量。

rinscript.sh脚本中,调用remplace函数时的代码是:

对应的RESTART_FILEIN就是传入remplace函数的的第一个变量$1NONE就是传入的第二个变量$2(上例此处是空值)

还有其他的传入变量,如$0是执行脚本的文件名。了解更多Shell的传入变量可以看菜鸟教程Shell 传递参数,变量的创建、修改和调用可以看菜鸟教程:Shell 变量

sed命令

sed命令是一个以行为单位处理文本的命令。原函数中还有>>r2,这是数据流重定向的内容,后面会写。

上面这段代码是使用sed函数,将run.def中含有变量$1的这一行给删掉了,并将结果输出。

remplace函数中,引号内表示对行内容进行怎样的操作,"/$1/D"表示:

上例中紧接着的run.def表示sed命令是从这个文件读入数据的,处理的是run.def文件的内容,并将数据输出到standard output。在没有设定的情况下是输出到屏幕,但是函数中在行末还加上了> r2,这就进行了数据流重定向,standard output的内容输出到了r2文件中,没有输出到屏幕。

sed命令的功能很多很强大,老师在这里的写法也有些特殊。这里使用Dd实现的功能是相同的,但是D涉及到pattern space中newline的问题,这里其实用不到,d够用了。

sed的常见用法菜鸟教程:sed命令就够用,详细用法建议使用info命令查看:

数据流重定向

前面我们提到了standard input 和standard output,命令会从standard input中读入数据,并输出数据到standard output。在没有专门设定的时候,standard input是从键盘读入,standard output是输出到屏幕。但有时候在脚本中,我们没法从键盘读入,又需要输出数据到文件,这时候就可以用重定向来设定standart input/ouput的来源和去向。

>>>设定了standard output的去向。remplace函数中> r2就是将sed输出到standard output的内容从屏幕重定向到了r2文件,本来输出到屏幕,现在改成了r2。而>>>的区别是,前者会创建一个新文件,并储存输出的内容;后者会检测这个文件是否已存在,如果存在输出的内容会累加到这个文件的最后,如果不存在的话会新建文件并储存输出的内容。

所以脚本中 >>r2就是将cat命令的standard output重定向到了r2,而且是以累加的形式添加到r2文件上的。

<可以设定standard input的来源,使得从键盘获取输入的命令也能从文件获取输入。

 

<<虽然长的和<很像,但它不属于数据流重定向,而是here documents的知识点。在cat命令的使用部分会讲。

cat命令的使用

示例:

例1中,输入命令并回车后,会在屏幕上看到/etc/issure这个文件的内容。

例2中,输入命令后,会发现命令提示符消失了,此时你能够通过键盘输入,并能在屏幕上看到输入结果。但此时会发现无法停止输入的状态,回车变成了换行而不再具有执行命令的功能。此时你需要做的是ctrl+D来结束输入。

类似的,命令行中用ctrl+D可以结束输入。(还有一个ctrl+C能够中止命令执行,也很好用。)

cat是像例2一样,没有指定文件,需要standard input,就是下一行的$1=$2。remplace函数脚本执行的时候是不需要按ctrl+D的,那如何结束输入状态呢?、

这就用到here document,脚本是通过<<END来实现。第一个<<设定了中止输入的字符,后续的内容都作为standard input,直到输入了<<后面紧跟的字符后,就相当于按下了ctrl +D,停止了输入状态1

>>r2是数据流重定向,经测试发现 <<>>的先后顺序是没有影响的。

改写remplace函数

回头看看remplace函数做了什么呢?

  1. run.def中要修改的行删掉,并输出到r2文件
  2. 将修改的行添加到r2文件的最后
  3. r2文件重命名为run.def文件

同样的功能还能通过哪些方法实现呢?

欢迎通过邮件和我交流cnqdcyq@163.com


1 END其实何以换成任意字符串。这部分是here document的知识,可以看菜鸟教程中here documents的部分。