Vi(详细版)

Vi 编辑器的扩展笔记,比基础版更详细

Editors

  • Programs that let you interactively edit text files,即交互式编辑文本文件的程序有:
    • DOS: edlin, edit
    • Windows: notepad, wordpad
    • Unix: ed, vi, vim
    • GNU: emacs
    • xedit, gedit, nano, pico
  • 文字处理器,带排版、字体、图片、分页等能力,保存的通常不是纯文本(如 .doc/.docx/.odt/.pdf 等)
    • WordStar, MSWord, Framemaker, Acrobat…
    • StarOffice, OpenOffice, LibreOffice

vi Modes

  • Command Mode 命令模式
    • vi 启动后为命令模式
    • 每一个按键执行一个编辑命令
    • 输入 : 进入命令行模式(command line mode)
  • Insert Mode
    • 只有在 Insert mode 下,才可以做文字输入, [ESC] 键可回到命令行模式
    • 通过输入几个插入命令之一来进入

img

  • 简单 vi 示例
    • vi tmp.txt #在命令模式启动
    • a #进入输入模式,在光标后追加append内容
    • ESC #退出输入模式,回到命令模式
    • :wq #保存write并退出quit

Easier Ways for Practicing

  • vim:vi 的升级版
  • vimtutor:参考教材,这是 Vim 自带的交互式教程,它不是编辑器,而是教你用编辑器的课本
  • gvim:带 GUI 的 vi

Cursor Movement(命令模式)

  • 可以用方向箭头键进行光标移动
  • 可以用 hjkl 代替箭头
    • [n] h #左移 n 位
    • [n] j #下移 n 位
    • [n] k #上移 n 位
    • [n] l #右移 n 位
  • 还有许多更高级的光标移动命令

屏幕间移动(命令模式)

  • ^F #Forward one screen
  • ^B #Back one screen
  • ^D #Down half screen
  • ^U #Up half screen

行内移动(命令模式)

  • $ #end of current line,到行
  • ^ #beginning of text on current line,到本行第一个非空字符,主要是跳过Tab或者空格等
  • 0 #beginning of current line,到行

单词间移动(命令模式)

  • [n] w #forward [n] word(s),按词往前走
  • [n] b #back [n] word(s),按词往后走
  • e #end of word,走到词最后

搜索跳转

行内字符搜索(命令模式)
  • f character #forward to next this character,移动到下一个这个字母
全文搜索(命令模式)
  • / pattern string #go to matched pattern downward,向下搜索pattern string
  • ? pattern string #go to matched pattern upward,向上搜索pattern string
  • 上面这两个和man里面的查找操作是一样的

下面这两个是在/ 时使用的

  • n:跳到下一个匹配(next)
  • N:跳到上一个匹配(反方向的 next)
  • 一般来说,如果小写是对后面进行操作,大写就是反向

行间跳转(命令模式)

  • G Go to last line of file
  • [n] G go to line [n],Go 到第n行

Inserting Text

这些命令都是在命令模式下按的,只是进入插入模式的位置不同而已

  • i #insert text before the cursor,在当前的光标前插入东西
  • a #append text after the cursor,在当前的光标后插入东西
  • I #Insert text at beginning of line,在行首加入东西
  • A #Append text at end of line,在行末加入东西
  • o #open new line after current line,在当前行后面加一行,插入东西
  • O #Open new line before current line,在当前行前面加一行,插入东西

大写一般都是对的操作

Deleting Text

这些命令是如何在命令模式下删东西

  • dd #delete current line,会删到缓存区buffer,可以用 p 粘贴(复制到光标后面),所以删除其实也等于剪切
  • [n] dd or d [n] d #delete [n] line(s),3dd或者d3d从当前行开始删3行
  • [n] dw #delete [n] word(s)
  • D #Delete from cursor to end of line,从光标删到行尾,一般大写都是对行的操作
  • x #delete current character,删除当前的字符
  • [n] x #delete [n] characters
  • [n] X #delete previous [n] character,删除光标之前的字符,相当于backspace

Changing Commands

这些命令也都还是在命令模式下执行

  • s/S #Substitute,将该处 character 删除,并进入插入模式,等待你输入新的字符,S是删除一整行
  • r,把光标下的字符直接替换replace成你接下来输入的那一个字符,但仍然是命令模式
  • R,进入替换模式:你打字会持续覆盖后面的字符,直到按ESC键退出
  • cw #change word,从光标位置开始,把“到单词结束”的内容删掉,然后进入插入模式让你输入新词
  • [n]cw #change next [n] word(s),删除n个单词,然后进入插入模式让你输入新词
  • c$ #change from cursor to end of line,从光标位置开始,到行尾$全部清掉,然后进入插入模式
  • ~ #change case of character,把光标下字母大小写翻转
  • J #Join current line and next line,把下一行移到该行后面
  • u #undo the last command just done,即撤回
  • . #repeat last change, redo,重复上一次动作
  • [n]yy or y[n]y #yank [n] line(s) to buffer,yank复制
  • [n]yw #yank [n] word(s) to buffer,复制单词
  • p #put yanked or deleted text after cursor,复制到光标后面(如果是一整行,就复制到光标所在行的后面一行)
  • P #Put yanked or deleted text before cursor,复制到前面
  • 4dd10jp
    • #1 4dd 删除 4 行
    • #2 10j 光标下移 10 行
    • #3 p 将删除的 4 行复制到光标后

Command Line Mode命令行模式

  • Enter command line mode by typing a :,输入:可以到命令模式
  • Line indicators 行定位符
    • :``20:移动到第 20 行,如 :20
    • :``. current line:将光标移至本行首
    • :``$ last line:将光标移至整文的行末
    • :``+, -, .+5, -10:光标向上向下移动几行;$-3 意思为光标先移动到最后一行,然后再向上移动 3 行

File Manipulation

  • :wq #write changes and quit
  • :w! # ! force overwrite of file,即强制保存
  • :q #quit if no changes made
  • :q! #quit without saving changes ! ,即强制退出,不保存退出
  • :![cmd] #shell escape,即暂时跳到外面的 shell 里 ! 执行[cmd]例如 :!ls:!pwd
  • :r [file] # r=read insert file at cursor position,即把其它文件的内容插入到后面,默认会换行

Configuring vi Session

  • :set all #display all option settings,显示所有的选项设置(q退出)
  • :set ignorecase #ignore the case of a character in a search,先设置再搜索,忽略大小写查找,使用 set noignorecase 进行关闭
  • :set number #display line numbers,显示行号
  • :set nonumber #turn off line numbers,关闭行号显示

Line Manipulation

  • :number #locate,移动到对应行
  • :n1,n2 m n3 #move,将 n1 到 n2 行,移动到 n3 行后的位置,会自动换行
  • :n1,n2 d #delete
    • :.,$-2 d #删除当前行到倒数第 3 行,.当前行,$最后一行
    • :1,. d #删除第 1 行到当前行

Substitution

  • :[Addr]s/old-expr/new-string/[g]
    • [Addr]表示“在哪些行做替换”,不写只对当前行
    • s:表示替换substitude操作,g 表示全局global替换,省略 option 时仅对每行第一个匹配串进行替换
    • :s/hte/the/g #当前行所有 hte 换为 the
    • :2,30s/use/used #将 2-30 行每行第一个 use 换位 used
    • :1,$s/Oct\./Nov. #将 1 到最后一行每行第一个 Oct. 换成 Nov.。注意,这里将 . 视为普通的点,所以文本匹配的是 Oct. 而不是 Oct
    • :1,$-3s/Oct\./Nov./g #将 1 到倒数第 4 行所有 Oct. 换成Nov.
1. :%s/old_exp/new_exp/g

这是一个最经典的全局替换命令。

  • ::进入底行模式(Command-line mode)。
  • %:范围修饰符,表示全文(从第一行到最后一行)。
  • s:代表 substitute(替换)。
  • /old_exp/:查找目标,即你想被换掉的旧字符串或正则表达式。
  • /new_exp/:替换内容,即你想换成的词。
  • /g:标志位 global(全局)。意味着替换每一行中出现的所有匹配项。如果没有这个 g,每行只会替换第一个匹配到的词。

总结: 在整篇文章中,把所有的 old_exp 替换为 new_exp


2. :1,$-3s/Oct\./Nov./g

这是一个带有限定范围和特殊字符转义的替换命令。

  • 1,$-3:这是指定的行范围
    • 1:从第 1 行开始。
    • $:代表最后一行。
    • $-3:代表倒数第 4 行(最后一行往上数 3 行)。
    • 所以这个范围是:从第 1 行到倒数第 4 行
  • s:替换操作。
  • /Oct\. /:查找目标。
    • 这里的 \. 是关键,因为在正则表达式中 . 代表任意字符,所以需要用反斜杠 \ 进行转义,表示匹配真实的“句点”。
    • 即:查找字符串 Oct.
  • /Nov./:替换为 Nov.
  • /g:行内全局替换。

总结: 在第 1 行到倒数第 4 行的范围内,将所有的 Oct. 替换为 Nov.

正则表达式

Regular Expression** - the basics and examples (meta-characters in REP)

不要将正则表达式与用于匹配文件名的“通配符”(Wildcards)混淆

正则表达式 (Regular Expression) 基础笔记

整理自 ICCAD_V49_3.pdf (第 18-23 页)

简介 (Page 18)

正则表达式(Regular Expressions,简称 RE 或 Regex)是一种强大的文本处理工具。

  • 功能:允许对文本内容进行模式匹配(pattern matching)。
  • 构成:由普通字符(normal characters)和特殊字符(即元字符,meta-characters)组合而成。
  • ⚠️ 核心警告切勿将其与 Unix Shell 中用于匹配文件名的“通配符”(Wildcards)混淆! 两者虽然符号相似,但含义不同。

易混淆概念:Shell 通配符 (Wild Cards) (Page 19)

在进入正则之前,必须先明确 Unix Shell 中用于文件名匹配的通配符。这些不是正则表达式。

符号含义适用 Shell
?匹配指定位置的任意单个字符所有
*匹配任意长度的字符串(包括零个字符)所有
abc...匹配括号内的任意一个字符所有
a-e匹配指定范围内的任意一个字符(如 a 到 e)所有
!def匹配除括号内字符以外的任意字符sh/bash
{abc,bcd}匹配逗号分隔的字符序列集合(不能有空格)bash/csh
~当前用户的主目录 (Home directory)bash/csh
~user指定用户的主目录bash/csh

应用场景对比 (Page 20)

特性通配符 (Wild Card)正则表达式 (Regular Expression)
处理对象文件名 (File names)文本内容 (Text patterns)
典型命令ls, cp, rm (如 ls *.c)grep, sed, awk, vi
编程语言Shell 脚本Tcl, Perl, Python, C++ 等
Vi 编辑器/ (查找), ? (反向查找), (替换)

正则表达式语法详解 (Page 21-22)

正则表达式主要由三种形式构成:

  1. 锚点 (Anchors):将模式绑定到行的特定位置(如行首、行尾)。
  2. 字符集 (Character sets):匹配特定位置的单个字符。
  3. 修饰符 (Modifiers):指定前一个表达式重复的次数。

核心元字符表

符号描述示例
.匹配除换行符以外的任意单个字符b.t 匹配 bat, bet, bit
*匹配其前面的元素零次或多次
(注意:不同于通配符中的“任意字符串”)(+是一次或多次;?是零次或一次)
ab*c 匹配 ac, abc, abbc...
abc匹配括号内的任意一个字符cbat 匹配 cat, bat
a-d匹配指定范围内的任意一个字符0-9 匹配任意数字
^abc取反:匹配不在括号内的任意字符^0-9 匹配非数字字符
^行首锚点:表达式必须出现在行开头^Start 匹配以 Start 开头的行
$行尾锚点:表达式必须出现在行末尾End$ 匹配以 End 结尾的行
\转义字符:将下一个特殊字符视为普通字符. 匹配实际的点号

实例分析 (Page 23)

以下是一些常见的正则表达式及其匹配含义:

正则表达式匹配含义匹配示例
cat字符串 "cat""cat"
.at任意字符后跟 "at""cat", "rat", "mat", "bat"
xy*z一个 x,后跟零个或多个 y,再跟一个 z"xz", "xyz", "xyyz", "xyyyz"
^cat出现在行首的 cat"category..." (位于行首)
cat$出现在行尾的 cat"...tomcat" (位于行尾)
*字符星号本身 (Literal asterisk)"*"
cCat"cat" 或者 "Cat""cat", "Cat"
^a-zA-Z任意非字母字符"1", "@", " " (空格)
0-9$以数字结尾的行"Item 5", "Year 2023"
[A-Z]A-Z*一个或多个大写字母"A", "US", "UNIX"
A-Z*零个或多个大写字母 (匹配任何内容,即使为空)"" (空串), "ABC"

注:此文档基于 ICCAD_V49_3.pdf 生成,旨在辅助理解 Unix 环境下的文本处理基础。

Vi
Shells

评论区