替换

  • 替换命令

    • 指定范围

    • 替换前确认

    • 与上下文相关的替换

  • 模式匹配

    • 用在搜索模式中的元字符

    • POSIX方括号表达式

    • 用在替换字符串中的元字符

  • 替换示例

常用命令(在命令模式下)

| 命令 | 说明 |

|------------------|-----------------------------|

| :g/pattern | 查找移动到文件中最后一次出现pattern的地方 |

| :g/pattern/p | 查找并显示文件中包含pattern的地方 |

| :g!/pattern/nu | 查找并显示文件中不包含pattern的地方,并显示行号 |

| :1,10g/pattern/p | 查找并显示第1行到第10行之间包含pattern的地方 |

g不光可以用于全局搜索,也可以用于全局替换

替换命令

编辑文件中已使用过简单的替换命令,如r,R,s,S等;它们只能进行局部等相对小范围的文本替换,如果需要从头到出现的文本一起进行替换,就需要全局替换

:g(global 全局)

:s(substitute 替换)

替换基本命令语法

:[range]s[substitute]/{pattern}/{string}/[flags]

  • range 表示范围 eg 10,20 表示10到20行 % 表示所有

  • pattern 要替换的模式

  • string 替换后的文本

  • flags 替换标志位

    • g(global) 表示全局范围内执行

    • c(confirm) 表示确认,可以确认或者拒绝修改

    • n(number) 报告匹配到的次数而不替换,可以用来查询匹配的次数

:s/old/new/

它会将当前这一行中第一个出现的模式old改为new;斜线/用来分隔命令的各部分

常用命令(在命令模式下)

| 命令 | 说明 |

|-----------------|-------------------------------|

| :s/a1/a2/g | 将当前光标所在行中的所有 a1 用 a2 替换 |

| :n1,n2s/a1/a2/g | 将文件中 n1 到 n2 行中所有 a1 都用 a2 替换 |

| :%s/a1/a2/g | 将文件中所有的 a1 都用 a2 替换 |

指定范围

在:s前面可以加上范围限制

| 命令 | 说明 |

|--------|------------------|

| :s | 当前行 |

| :1,10s | 第1行到第10行 |

| :1,$s | 第1行到最后一行 |

| :%s | 可以使用%代替1,$,表示所有行 |

替换前确认

:1,10s/old/new/gc

当不太确定能否按预期正确替换时,可以在命令结尾加上c选项 代表confirm 确认

如果确定要替换,必须输入y (yes) 再按下回车,如果不想做替换,直接按下回车,即可跳过当前文本,跳转到下一个匹配文本

与上下文相关的替换

:g/pattern/s/old/new/g

简单替换会把所有匹配全部替换成新的文本,有时替换会更复杂一些,比如要替换的字符会出现在很多单词当中;

这种语法是先搜索一个模式,在找到包含模式的某一行时,对另外一个字符old做替换

第一个g告知命令需对文件中所有的行起作用,pattern用于识别发生替换的行,遇到包含pattern的行,old替换成new,g表示在哪一行中做全局替换

模式匹配

在全局替换时,不只可以搜索固定的字符串,也可以搜索可变的模式,也就是正则表达式

正则表达式是将一般的字符与许多特殊的元字符结合起来的表达式

用在搜索模式中的元字符

| 命令 | 说明 |

|-------|------------------------------------------------|

| . | 匹配出任何单一字符(换行符除外),空格也是字符 |

| * | 匹配出位于此符号前的单一字符,该字符可出现任意次,包括0次 |

| ^ | 从行头开始匹配 |

| $ | 匹配位于行尾 |

| \ | 将后面的特殊字符当成一般字符 |

| [] | 匹配出方括号里的任何一个字符,插入符号^只有位于方括号第一个时才有特殊的意义,表示取反 |

| ( ) | 将(与)间的模式保存到保留缓冲区 |

| < > | 会匹配出以某些字符开头(<)或(>)结尾的单词,单词的结尾和开头是由标点符号或空格来分隔 |

| ~ | 匹配出任何一上次搜索时所使用的正则表达式 |

POSIX方括号表达式

POSIX方括号表达式,用于比较非英文字母的字符;在方括号表达式中,可以包括:

  • 字符类 包括了用[:与:]括起来的关键字,关键字描述了不同的字符类,包括字母字符,控制字符等等

  • 校对符号 由多字符组成的序列,但必须被当成一个单位,使用[.与.]括起所需字符

  • 等价类 列出了所有应该被当成相等的字符集合 用[=与=]括起来

这三种都必须出现在方括号表达式的方括号中。例如 [[:alpha:]!] 匹配出任何一个字母字符或是感叹号

| 命令 | 说明 |

|------------|------------------|

| [:alnum:] | 字母与数字字符 |

| [:alpha:] | 字母字符 |

| [:blank:] | 空格与制表符 |

| [:cntrl:] | 控制字符 |

| [:digit:] | 数字字符 |

| [:graph:] | 可打印的与可见的字符 不包括空格 |

| [:lower:] | 小写字符 |

| [:upper:] | 大写字符 |

| [:print:] | 可打印字符 包括空白 |

| [:punct:] | 标点字符 |

| [:space:] | 空白字符 |

| [:xdigit:] | 十六进制数字 |

用在替换字符串中的元字符

:%s/[ABC]/[abc]/g

希望将ABC换成abc,但是因为在替换字符串中的方括号会被当成一般字符

要解决这个问题,需要一个方式来指定变动的替换字符串

  • \n

利用(与)存储的第n个模式的文字做代换,n表示为数字1-9,而之前存储的模式是从行左至右来计算的

  • \

将后面一特殊字符当成一般字符。反斜线在替换字符串中与搜索模式中同样是元字符。要指定匹配真正的反斜线,需要输入两个\

  • &

用在替换字符串中时,会被替换成搜索模式匹配出的完整文本,这在避免重新输入文本时很有用

  • ~

与使用在搜索模式时的意义类似,找到的字符串会被最后一个替换命令中的替换文本替换

  • \u或\l

使替换字符串中的下一个字符变成大写或小写

  • \U或\L 与 \e或\E

与\u \l 类似,只是所有接在后面的字符都会被转换成大写或小写,一直到替换字符串结束,或出现\e \E为止

所有的模式都对大小写敏感,但是可以在模式中同时指定匹配大写与小写

替换示例

  • 替换所有 time 为 date

:%s/time/date/g

%表示所有,等同于 1,$;s表示替换;g 表示替换全局;

这种替换在实际中往往会误伤,比如datetime :%s/<time>/date/g

  • 给脚本中的time加上()号,表示函数调用

:%s/time/&()/g

  • 更改路径

%s//home/tim//home/git/g

如果斜线作为替换文本或模式的一部分时,必须使用反斜线做转义,用/才能得到/

或者使用冒号当作分隔符 :%s:/home/tim:/home/git:g

  • 将单词转换成大写

:%s/[Hh]elp/HELP/g

:%s/[Hh]elp/\U&/g

  • 将多个空格替换成一个空格

:%s/ */ /g

  • 将sh脚本 1-10行注释

:1,10s/^/# /g

  • 为当前行开始后5行添加;

:.,+5s/$/;/g

可不加g,本来就只会有一个结尾

  • 将:或=后面的多个空格换成1个空格

:%s/([:=]) */\1 /g

使用\1表示 (与) 匹配出来的字符

  • 删除空白行

:g/^$/d

:g/^[ ]*$/d

  • 将列调换

:%s/(.) - (.)/\2 - \1/g

-分隔列,将列调换

  • 将文件的行次序反向

:g/.*/mo0

:g/^/mo0

  • 将以数字开头的行移到文件结束

:g/[0-9]/m$