行文本编辑器ed
命令介绍
对ed命令中实现起来相对可行的部分进行了提取和修改,内容如下:
ed有两个模式,命令模式和输入模式。在命令模式下输入的是命令,这些命令用来指定对编辑文本的操作;输入模式下输入的都是文本(除了退出输入模式的命令),
这些文本将依照命令模式下的命令,被直接添加或替换到文本中。
可以通过ed file或者ed进入ed编辑器,进入时不需要输出或打印任何内容。两者有所区别。前者读取file文件的内容到编辑器缓存中,后续操作基于缓存中的内容。
后者直接操作空的编辑器缓存。所有输入影响的对象是编辑器缓存中的内容,在命令模式下可以通过保存命令将文本保存到指定文件中。
初始默认进入命令模式。命令模式通过"a"、"i"、"c"命令(后续详细介绍)进入到输入模式,
输入模式通过"."退出到命令模式。
在命令模式中,ed命令是由0、1或2个地址,后接一个单字符命令,以及参数(可能没有)组成。ed命令的结构如下:
[地址[,地址]]命令[参数]
地址部分指定了命令起作用的一行或多行文本。如果给出的地址少于命令接受的地址,则使用默认地址。
测试时只测试完整的ed命令,不会单独测试地址。
地址部分包含如下元素:
.当前行——初始时,当前行默认为给定文本的最后一行。
$文本最后一行
n文本的第n行,如果没有,则输出'?'
-n从文本当前行数起,向前的第n行,如果没有,则输出'?'
+n从文本当前行数起,向后的第n行,如果没有,则输出'?'
m,n文本的第m到n行,n不小于m,否则输出'?'
,文本的所有行
;文本当前行到最后一行
/str/从文本当前行起(不包含当前行),下一个匹配str的行。如果有必要,搜索将从文本的开始处继续至当前行。匹配不到则输出'?'
?str?从文本当前行起(不包含当前行),上一个匹配str的行。如果有必要,搜索将从文本的末尾处继续至当前行。匹配不到则输出'?'
注1:m、n均为非负整数。'.'、'$'和'n'能够与'-n'和'+n'组合,成为更复杂的地址,实际上'-n'可表示为为'.-n','+n'可表示为'.+n'。
'm,n'中的m和n可由其他单行地址代替。
注2:每行有一个行号,行号从1开始。当内容为空时,当前行的行号为0。匹配的意思是行中包含这个str字符串。
命令为单个字符,其中一些命令有参数。需要实现解析的命令如下:(小括号里为默认地址)
基本命令:
ed file
(.)a切换到输入模式,将新输入的文本追加到指定行的后面,当前行被设为输入文本的最后一行。
(.)i切换到输入模式,将新输入的文本追加到指定行的前面,当前行被设为输入文本的最后一行。
(.,.)c切换到输入模式,将新输入的文本替换成指定行,当前行被设为输入文本的最后一行。
**(.,.)d删除指定行,如果被删除的文本后还有文本行,则当前行被设为该行,否则设为被删除的文本的上一行。
(.,.)p打印指定行的内容,当前行被设为打印行的最后一行。
($)=打印指定行的行号。
**(.+1)z[n]从指定行,一次向后移动n行,打印包含指定行以及其后n行的内容。当前行被设为最后被打印的行。当指定行到末尾行不足n行时,打印当前行到末尾行。
当参数n指定时,必为正整数;不指定时,打印当前行到末尾行。
q退出ed。当有更改的内容未保存到文件时,提示一次'?'。再次输入q,则放弃内容的更改,退出ed。
Q退出ed。不论有没有更改未保存,都不提示直接退出ed。
f [file]设置默认文件名,不打印任何内容。如果没有指定参数file,则打印默认文件名(没有默认文件名时,打印'?')。
通过ed file命令进入时,file被设置为默认文件名。通过ed命令进入时,没有默认文件名。
(1,$)w [file]保存指定行到指定文件,当前行不变。保存后不需要输出或打印任何内容。如果指定文件存在,则保存的内容覆盖文件内容。
如果文件不存在,则创建文件并保存内容。如果参数file不指定,则使用默认文件名代替参数file。当没有默认文件名时,参数file必须指定,
否则打印'?'提示。注意,w的file参数不会更改默认文件名。
(1,$)W [file]保存指定行到指定文件,当前行不变。保存后不需要输出或打印任何内容。保存形式为"追加保存",追加到文件末尾。
如果文件不存在,则创建文件并保存内容。其他使用情况参照w命令中的描述。
注:命令a、i、=、z的地址只会指定具体的一行,命令c、d、p、w、W的地址可以指定单行或多行。
进阶命令:
(.,.)m(.)移动左边源指定行到右边目的指定行后,当前行被设为移动行的最后一行。
(.,.)t(.)复制左边源指定行到右边目的指定行后,当前行被设为复制行的最后一行。
(.,.+1)j合并指定行内容,当前行被设为合并行。
(.,.)s[/str1/str2/count] (.,.)s[/str1/str2/g]
(.,.)s在指定行用str2替换str1。当最后为count(正整数)时,对指定的每一行,替换第count个匹配的str1(若该行没有,则不替换),
若不指定,即(.,.)s/str1/str2/,默认每一行替换第一个。当最后为g时,替换所有。当指定行没有符合要求的或没有第count个时,输出'?'。
(.,.)s重复上一次替换命令,当前行被设为最后一个被改变的行。
注1:命令m、t左地址可以指定单行或多行,右地址只能指定具体的一行。命令j的地址只会指定多行(可以是单字符指定的多行),
如果指定了一行,则对单行的合并相当于不做任何操作。
注2:这些命令不打印或输出任何内容。
高级命令:
(.)k[x]用一个小写字符'x'标记指定行,标记成功后,可以通过"'x"这个地址(英文单引号'加上字符x)来访问该行。
当被标记行被删除或修改后,该标记失效。在被标记行前后插入内容,或者移动被标记行时,该标记不会失效。可以对一行加多个标记,一个标记只能标记一行。
u撤销上一次改动文本的命令,当前地址被设为撤销改动后的最后一行。注意,撤销的是对编辑器缓存中文本的改动,
写入文件后,之前的改动不可撤销。可撤销多次。
所有文件保存在项目根目录下,不需要删除文件。
组合命令示例
2,4p打印2到4行内容
/a/p打印向后匹配到'a'的第一行的内容
-1a从当前行的前一行的之后插入内容
+2i从当前行的后两行的之前插入内容
1,2c将1到2行内容替换
$-2d删除倒数第3行
1,2W将1到2行内容追加写到文件
?favourite?ki标记向前匹配到"favourite"的那行为'i'
'iw favour将标记为'i'的那行保存到favour文件中
1.通用命令结构"[地址[,地址]]命令[参数]"中,各个[]部分可以是有或者没有的意思。具体说明如下:
地址部分可以为空、'地址'或'地址,地址';命令部分必须有;参数部分根据命令和输入,可以有,可以没有。
2.命令的地址为文档中描述的地址部分的组合,没有括号。
介绍命令的部分中,小括号部分内部是默认地址。什么是默认地址呢?就是你不输入地址部分、只有命令部分时,它被赋予的地址。
如对于(.)a,只输入a时,它的默认地址为'.',不需要括号或单引号。
README补充说明:
1.'=',不改变当前行。
2.(.,.)m(.) 当目标地址在源地址之间时,输出'?'的错误提示。
3.(.,.)t(.) 因为是复制,所以目标地址会在源地址之间。
4.0a,0i会进入输入模式,输入文本加在文本最前面。为了与描述相符,0c指令设为不合法。
5./str/和?str?能够与'-n'或'+n'组合。
6.j指令,如果地址指定了具体某一行时,对文本不进行操作,也不算对文本做任何改动。同时,当前行也不变。
7.标记一行为x后,"'x"视为一个地址,可以代入地址的运算中。如'x-2和'x,$等。
8.程序对u命令的要求中,不把撤销改动当作一次对文本内容的改动。
举例来说,你用a添加了几行,然后用d删除了几行。此时第一次u命令是撤销d命令对文本的改动,第二次u命令是撤销a命令对文本的改动。
9.u命令中,对README中“当前地址被设为撤销改动后的最后一行”的说明进行修正:u命令撤销上一次改动后,当前行(即'.'地址)被设为改动之前的当前行的地址。
举例来说,对于文件test_u,其内容内容如下:
test_u
001
dd
ff
对其进行如下操作:
ed test_u 当前地址设为4
2p 当前地址设为2
3a
aa
ww
. 当前地址设为5
,p 当前地址设为6
u 当前地址设为2,即"3a"命令执行之前的当前地址