【Vim Masterclass 笔记16】S07L32 + L33:同步练习09 —— 掌握 Vim 宏操作的六个典型案例(含点评课内容)
文章目录
- S07L32 Exercise 09 - Macros
- 1 训练目标
- 2 操作指令
- 2.1. 打开 macros-practice.txt 文件
- 2.2. 练习1:将旧版 Python 代码转换为新版写法
- 2.3. 练习2:根据列表内容批量创建 Shell 脚本
- 2.4. 练习3:对电话号码作格式化处理
- 2.5. 练习4:从日志文件中提取重要数据
- 2.6. 练习5:将多行数据压缩为一行
- 2.7. 练习6:从 HTML 中提取数据
- 3 退出 Vim
- S07L33 Exercise 09 - Macros - Walkthrough
写在前面
Vim 宏这部分知识点不仅讲解起来篇幅最长,同步练习环节的作业量也是全套课程中最多的。宏在 Vim 操作中不可撼动的核心地位由此可见一般。虽然今天有事耽搁了笔记整理,到家后的第一件事仍然是一步一个脚印地先在本地做一遍所有习题,然后再对照讲义完成翻译。这个过程不可能很快,但也是掌握 Vim 宏相关要点不可或缺的重要环节。我用自己的亲身经历奉劝各位,切忌急于求成,尤其不要在该筑牢基础的地方吝惜自己的时间和精力。要相信水滴石穿的力量,相信玉汝于成,功不唐捐。同步练习中列举的几个典型案例值得大家反复琢磨与演练。
S07L32 Exercise 09 - Macros
1 训练目标
练习 Vim 中的宏(macro)的创建与使用。1
2 操作指令
2.1. 打开 macros-practice.txt 文件
用 Vim 打开源码包内的练习文件 macros-practice.txt(默认解压到 Downloads 文件夹下):
cd Downloads
cd vimclass
vim macros-practice.txt
2.2. 练习1:将旧版 Python 代码转换为新版写法
给定一组旧版 Python 代码(v2.6 及以前版本),试将其改为新版写法(v3.0 即以上版本):将 print 语句改为 print() 函数。也就是说,需要对以下各行作如下处理——
由修改前的:
print "Macros are very fun!"
统一改为:
print("Macros are very fun!")
下面用 Vim 宏来实现。顺便提一下,本练习无需了解 Python 语法,本例旨在提供一个实际案例来练习 Vim 宏的相关操作。
其中一种参考方案实现如下:
- 光标定位到这一行:
print "Macros are very fun!" - 按 QA 启动宏录制并将其存入寄存器
"a; - 按 0 对光标作标准化处理,统一定位到行首;
- 按 FSpace 将光标定位到下一处空格位置;
- 按 R( 将当前空格替换为左小括号;
- 按 ShiftA) 在行尾添加一个右小括号,再按 Escape 切回正常模式;
- 按 J 将光标下移一行,以便
Vim宏快速重复操作; - 最后,按 Q 停止宏录制。
要查看寄存器 "a 中的录制内容,可输入命令 :reg a + Enter。内容如下:
"a 0f r(A)^[j
键入 @A 即可对下一行运行录好的宏;若要重复执行上一次宏操作,按 @@ 即可。余下各行均可使用 @@ 重复宏的运行。
注意
上述实现仅供参考,并非唯一的解决方案。例如将 FSpace 改为 T",也能将光标定位到同一处空格。只要能实现最终的效果就行。
2.3. 练习2:根据列表内容批量创建 Shell 脚本
给定一个用户列表,要求对列表中的每个用户分别执行一组相同的操作。为此,可以将某个用户的一系列操作录制为一个 Vim 宏,然后对其余用户执行这个宏即可。最终目标是将如下这段文本:
jason
sophia
jack
emma
ava
统一改为以下形式:
passwd -l jason && echo jason >> locked_users.txt
passwd -l sophia && echo sophia >> locked_users.txt
passwd -l jack && echo jack >> locked_users.txt
passwd -l emma && echo emma >> locked_users.txt
passwd -l ava && echo ava >> locked_users.txt
这组命令用户锁定 Linux 系统中的指定用户帐号,并将其帐号名追加到一个 locked_users.txt 文件中。命令的含义无关紧要,关键在于 Vim 的用法。本练习旨在提供一个实际的应用场景。
其中一种参考方案实现如下:
- 将光标定位到
jason这一行; - 按 QB 启动宏录制,并将其存入寄存器
"b; - 按 YAW 将用户名复制(yank)到默认寄存器;
- 按 ShiftI 从行首进入插入模式,并输入
passwd -l+ Escape; - 按 ShiftA 从行尾进入插入模式,并输入 Space +
&&+ Space +echo+ Space + Escape 返回正常模式; - 接着,按 P 粘贴未命名寄存器(unnamed register)中的内容;
- 按 A,并输入 Space +
>>+ Space +locked_users.txt,再按 Escape 切回正常模式; - 按 J 将光标下移一行,以便快速重复宏操作;
- 最后,按 Q 停止宏录制。
要查看寄存器 "b 中的录制内容,可输入命令 :reg b + Enter。内容如下:
"b yawIpasswd -l ^[A && echo ^[pa >> locked_users.txt^[j
对下一行执行宏操作,输入 @B 即可;后面三个类似的文本行,则可以用 3@B 轻松实现批量修改。
2.4. 练习3:对电话号码作格式化处理
接下来,创建一个 Vim 宏并存入寄存器 "p,实现将如下所示的电话号码:
2798265253
统一转换为符合美国人书写习惯的格式:
(279) 826-5253
其中一种参考方案实现如下:
- 将光标定位到
2798265253这一行(即待批量处理的第一行); - 按 QP 启动宏录制,并将其存入寄存器
"p; - 按 ShiftI 从行首进入插入模式;
- 输入左小括号
(,并按 Escape 回到正常模式; - 键入三次 L,让光标定位到
9处; - 按 A 在光标后添加文字,输入 )Space 后,按 Escape 返回正常模式。
- 按三次 L 将光标移至
6的下方; - 按 A- 插入一个连字符,再按 Escape 回到正常模式;
- 按 J 将光标下移一行,以便快速重复宏操作;
- 最后,按 Q 停止宏录制。
要查看寄存器 "p 中的录制内容,可输入命令 :reg p + Enter。内容如下:
"p I(^[llla) ^[llla-^[j
鉴于要处理的电话号码很多,文本行超出了屏幕,难以轻易获知需要重置执行多少次宏;此外,单纯使用 @@ 来重复执行也很费时间。此时应该使用指定具体范围来应用宏操作。先用 :set nu 开启行号,再将光标定位到第 25 行;然后按 Ctrl + F 向下翻页,确定最后一个电话号码的行号为 73。
接着输入 :25,73 normal @p + Enter,通过 normal 命令指定具体范围并批量运行宏操作。之后再通过 Ctrl + B 上翻查看宏的执行情况。
2.5. 练习4:从日志文件中提取重要数据
下一组练习取材自 Linux 服务器的系统日志。这些内容是本地 Linux 防火墙阻止连接请求的日志记录。我们的目标是分别提取出时间戳、尝试连接的源 IP 地址以及目标端口。
其中,SRC= 字样后的内容即为源 IP 地址,例如:SRC=190.18.193.152。
目标端口则位于 DPT= 字样后,例如:DPT=23。
也就是利用 Vim 宏(假设录制到寄存器 "l)将下面这样的日志内容:
Jan 13 09:57:01 www1 kernel: [3947771.808744] [BLOCK] IN=eth0 OUT= MAC=e6:e9:2d:04:b6:95:3c:8a:b0:0d:6f:f0:08:00 SRC=190.18.193.152 DST=2.5.9.1 LEN=40 TOS=0x02 PREC=0x00 TTL=51 ID=25120 PROTO=TCP SPT=12502 DPT=23 WINDOW=4078 RES=0x00 SYN URGP=0
批量精简为如下版本,并以逗号分隔:
Jan 13 09:57:01,190.188.193.152,23
其中一种参考方案实现如下:
- 将光标定位到以
Jan 13 09:57:01开头的这一行; - 按 QL 启动宏录制,并将其存入寄存器
"l; - 按 0 对光标作标准化处理,统一定位到行首;
- 按 TW 将光标定位到时间戳后面的空格为止;
- 输入
dtS删除当前光标到SRC=之间的所有内容; - 按 DW 删除
SRC; - 按 R, 将
=替换为逗号,; - 按 FSpace 将光标定位到 IP 地址后的空格处;
- 输入
d/DPT+ Enter 删除当前光标与DPT=之间的文字内容; - 按 DW 删除
DPT; - 按 R, 再将
=替换为逗号,; - 按 FSpace 将光标定位到端口号后面的空格处;
- 按 ShiftD 删除这一行当前光标及其后面的剩余内容;
- 按 J 将光标下移一行,以便快速重复宏操作;
- 最后,按 Q 停止宏录制。
要查看寄存器 "l 中的录制内容,可输入命令 :reg l + Enter。内容如下:
"l 0twdtSdwr,f d/DPT^Mdwr,f Dj
同样,还有其他方式可以实现上述任务。例如,要将 SRC= 改为 ,,除了用上面的 DWR 实现,还可以使用 2CW。不妨停下来思考一下类似的备选方案对录制的宏进行修改,看看能否达到同样的效果。
若要对下一行日志执行录制的宏,输入 @L 即可。如果没问题,就用 @@ 重复执行,直至处理完剩下的日志内容。
2.6. 练习5:将多行数据压缩为一行
再次强调,宏录制的是一系列按键操作。尽管我们一直在单行内容上练习宏的相关操作,宏也可以作用于多行。假如需要将下列三行通过录制的宏(假设存入寄存器 "c)按要求处理为一行,即从之前的:
Country China
1,380,950,000 people
处理为:
1,380,950,000;China
其中一种参考方案实现如下:
- 将光标定位到以
Country China开头的这一行; - 按 QC 启动宏录制,并将其存入寄存器
"c; - 按 0 对光标作标准化处理,统一定位到行首;
- 按 DW 删除单词
Country; - 按 J 将光标下移一行;
- 按 DShiftW 将数字存入未命名寄存器(unnamed register);
- 按 K 上移光标到刚才那行;
- 按 ShiftP 将数字粘贴到光标位置的前方;
- 按 R; 将空格替换为分号;
- 按 J 将光标下移一行;
- 按 2DD 删除当前行与下一行内容;
- 最后,按 Q 停止宏录制。
要查看寄存器 "c 中的录制内容,可输入命令 :reg c + Enter。内容如下:
"c 0dwjdWkPr;j2dd
接着,可以通过引入数量词,即 4@C,将上述宏操作再重复执行四次,实现该组数据的批量处理。
同样,要在 Vim 中实现上述效果还有很多其他方案可供选择。
2.7. 练习6:从 HTML 中提取数据
下列这行文本为一组 HTML 链接列表(即 <a> 标签):
<a href="#">@armyspy.com</a><a href="#">@cuvox.de</a><a href="#">@dayrep.com</a><a href="#">@einrot.com</a><a href="#">@fleckens.hu</a><a href="#">@gustr.com</a><a href="#">@jourrapide.com</a><a href="#">@rhyta.com</a><a href="#">@superrito.com</a><a href="#">@teleworm.us</a>
最终需要通过 Vim 宏(假设存入寄存器 "q)处理成下列效果:
armyspy.com
cuvox.de
dayrep.com
einrot.com
fleckens.hu
gustr.com
jourrapide.com
rhyta.com
superrito.com
teleworm.us
其中一种参考方案实现如下:
- 将光标定位到以
<a开头的文本行; - 按 QQ 启动宏录制,并将其存入寄存器
"q; - 按 DF@ 删除当前光标到
@之间(包含@)的所有内容; - 按 F< 将光标定位到下一处
<位置; - 按 CF> + Enter + Escape,将
</a>替换为一个换行标记; - 最后,按 Q 停止宏录制。
要查看寄存器 "q 中的录制内容,可输入命令 :reg q + Enter。内容如下:
"q df@f<cf>^M^[
输入 @Q 即可运行这个宏。继续重复执行,按 @@ 即可,直至处理完其余链接内容。
3 退出 Vim
若要放弃文件变更以便下次重新练习,使用退出命令 :q! + Enter。
S07L33 Exercise 09 - Macros - Walkthrough
本节为同步练习点评课,视频本身没有增补知识点。这里仅对实操过程中的几个问题进行复盘:
- 除了宏录制前后需要注意光标的归一化处理(即回到行首、下移一行之类),还应将运行宏操作前的 内容查看环节 作为另一项最佳实践(上述练习均包含该步骤)。这样做,一来可以直观了解用到的特殊符号的写法;二来可以及时发现操作过程中出现的问题;
- 在重复运行宏时,如果此前从未执行过宏,使用 @@ 可能会出错。最好先用
@{macro_name}的形式运行宏; - 批量处理最容易出错的地方,往往不在待处理内容中间,而在 最后一个待处理项 上。例如练习 6 中的链接内容提取,第一次尝试录制宏时,在分离
</a><a>时选择了先删除</a>再用 I 键插入一个回车符。处理到最后一个链接时,由于闭标签后没有下一个<a>,再用 I 键插入回车符会让最后一个字符s与前面的内容分离。既然是批量操作,就应当一气呵成,切忌在这样的临界点位置拖泥带水。
本节练习另附精美排版 PDF 格式,阅读体验更佳,详见:
vimclass/Exercise-09-Macros.pdf↩︎
相关文章:
【Vim Masterclass 笔记16】S07L32 + L33:同步练习09 —— 掌握 Vim 宏操作的六个典型案例(含点评课内容)
文章目录 S07L32 Exercise 09 - Macros1 训练目标2 操作指令2.1. 打开 macros-practice.txt 文件2.2. 练习1:将旧版 Python 代码转换为新版写法2.3. 练习2:根据列表内容批量创建 Shell 脚本2.4. 练习3:对电话号码作格式化处理2.5. 练习4&…...
爬楼梯问题(Leetcode 第70题)
爬楼梯问题(Leetcode 第70题) 问题描述 假设你正在爬楼梯。每次你可以爬 1 个或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n 2 输出:2 解释:有两种方法可以爬到楼顶。…...
6.5 正定矩阵
一、正定矩阵 这一节关注的是特征值都是正数的对称矩阵。如果对称使得矩阵很重要,那么这个额外的性质(所有的 λ > 0 \lambda>0 λ>0)会使得它更加的特殊。我们所说的特殊并不表示它稀有,特征值都是正数的对称矩阵几乎…...
verilog笔记1
1. 阻塞赋值 阻塞赋值,顾名思义即在一个 always 块中,后面的语句会受到前语句的影响,具体来说就是在同一个always 中,一条阻塞赋值语句如果没有执行结束,那么该语句后面的语句就不能被执行,即被“阻塞”。也…...
游戏引擎学习第81天
仓库:https://gitee.com/mrxiao_com/2d_game_2 或许我们应该尝试在地面上添加一些绘图 在这段时间的工作中,讨论了如何改进地面渲染的问题。虽然之前并没有专注于渲染部分,因为当时主要的工作重心不在这里,但在实现过程中,发现地…...
git系列之revert回滚
1. Git 使用cherry-pick“摘樱桃” step 1: 本地切到远程分支,对齐要对齐的base分支,举例子 localmap git pull git reset --hard localmap 对应的commit idstep 2: 执行cherry-pick命令 git cherry-pick abc123这样就会将远程…...
监控与调试:性能优化的利器 — ShardingSphere
在分布式数据库系统中,监控和调试是确保系统高效运行的关键。ShardingSphere 提供了多种监控和调试工具,帮助开发者实时跟踪和优化性能,识别瓶颈,进行故障排查,从而提升系统的稳定性和响应速度。本文将介绍如何使用 Sh…...
LLVM - 编译器前端 - 理解BNF(巴科斯-诺尔范式)
一:概述 BNF(Backus-Naur Form,巴科斯-诺尔范式)是一种用于描述上下文无关文法的形式语言,广泛应用于定义编程语言、协议和文件格式的语法规则。 下面是一小段类Pascal编程语言,这个编程语言就可以用BNF描述。用BNF描述编程语言的语法规则之后,就可以根据这个规则生成抽…...
服务化架构 IM 系统之应用 MQ
在微服务化系统中,存在三个最核心的组件,分别是 RPC、注册中心和MQ。 在前面的两篇文章(见《服务化架构 IM 系统之应用 RPC》和《服务化架构 IM 系统之应用注册中心》)中,我们站在应用的视角分析了普适性的 RPC 和 注…...
ELF2开发板(飞凌嵌入式)基本使用的搭建
ELF2开发板(飞凌嵌入式) 开箱包裹内容 打开包装,你可以看到以下物品 一个绿联的usb3.0读卡器、sandisk的32g内存卡(太好了)rk3588 4g32g emmc版本ELF2开发板输出为12v 3A的电源适配器(和ipad的充电器外观好像) 图1 外…...
Appium(四)
一、app页面元素定位 1、通过id定位元素: resrouce-id2、通过ClassName定位:classname3、通过AccessibilityId定位:content-desc4、通过AndroidUiAutomator定位5、通过xpath定位xpath、id、class、accessibility id、android uiautomatorUI AutomatorUI自…...
简单的sql注入 buuctf
lovesql 这道题是一个非常简单的sql注入 也就是万能密码 我们只需要注意在输入用户名的地方使用 ’ 将语句提前终止 并且or一个为真的条件 这样整个语句的结果就为真 这就是万能密码的原理 这样我们就得到了密码 然后我们发现这只是密码 于是查看一下字段数 尝试下注入 这里我…...
Ubuntu 24.04 LTS 空闲硬盘挂载到 文件管理器的 other locations
Ubuntu 24.04 LTS 确认硬盘是否被识别 使用 lsblk 查看信息,其中sda这个盘是我找不到的,途中是挂在好的。 分区和格式化硬盘 如果新硬盘没有分区,你需要先分区并格式化它。假设新硬盘为 /dev/sdb,使用 fdisk 或 parted 对硬盘…...
<电子幽灵>开发笔记:BAT基础笔记(一)
BAT脚本基础笔记(一) 介绍 费曼学习法最重要的部分,即把知识教给一个完全不懂的孩子——或者小白。 为了更好的自我学习,也为了让第一次接触某个知识范畴的同学快速入门,我会把我的学习笔记整理成电子幽灵系列。 提示:作为低代码…...
PiliPalaX ( 第三方安卓哔哩哔哩)
PiliPalaX 是一款哔哩哔哩第三方客户端。使用 Flutter 开发,基于PiliPala原版基础上创作出来的X升级版,目前支持Android、IOS客户端。 应用特色 目前着重移动端(Android、iOS)和Pad端,暂时没有适配桌面端、手表端等 https://pan.quark.cn/s/…...
在亚马逊云科技上高效蒸馏低成本、高精度的Llama 3.1 405B模型(上篇)
在2024年的亚马逊云科技re:Invent全球云计算春晚里,亚马逊云科技CEO - Matt Garman介绍了亚马逊云科技的AI模型托管平台Amazon Bedrock上的模型蒸馏服务Model Distillation,令小李哥印象十分深刻。该功能可自动化地为特定场景的知识创建一个蒸馏模型。它…...
Amazon MSK 开启 Public 访问 SASL 配置的方法
1. 开启 MSK Public 1.1 配置 MSK 参数 进入 MSK 控制台页面,点击左侧菜单 Cluster configuration。选择已有配置,或者创建新配置。在配置中添加参数 allow.everyone.if.no.acl.foundfalse修改集群配置,选择到新添加的配置。 1.2 开启 Pu…...
LeetCode_438.找到字符串中所有字母异位词
给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 示例 1: 输入: s "cbaebabacd", p "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "cba", 它是 "a…...
一文读懂服务器的HBA卡
什么是 HBA 卡 HBA 卡,全称主机总线适配器(Host Bus Adapter) ,是服务器与存储装置间的关键纽带,承担着输入 / 输出(I/O)处理及物理连接的重任。作为一种电路板或集成电路适配器,HBA…...
Debezium日常分享系列之:对于从Oracle数据库进行快照的性能优化
Debezium日常分享系列之:对于从Oracle数据库进行快照的性能优化 源数据库Kafka Connect监控测试结果 源数据库 Oracle 19c,本地,CDB数据库主机的I/O带宽为6 GB/s,由此主机上运行的所有数据库共享临时表空间由42个文件组成&#x…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
