Linux:编辑器Vim和Makefile

✨✨所属专栏:Linux✨✨

✨✨作者主页:嶔某✨✨

vim的三种常用模式

分别是命令模式(command mode)、插入模式(Insert mode)和底行模式(last line mode)

各模式的功能区分如下:

  1. 正常/普通/命令模式(Normal mode) 控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode。
  2. 插入模式(Insert mode) 只有在Insert mode下,才可以做文字输入,按「ESC」键可回到命令行模式。该模式是我们后面用的最频繁的编辑模式。
  3. 末行模式(last line mode) 文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。 在命令模式下,shift+: 即可进入该模式。要查看你的所有模式:打开vim,底行模式直接输入
cpp 复制代码
:help vim-modes

vim的基本操作

进入vim

输入vim+文件名 进入vim的命令模式

cpp 复制代码
vim code.c

正常模式切换为插入模式

  • 输入a:在当前字符的下一个字符进入插入模式
  • 输入i:在当前字符进入插入模式
  • 输入o:另起一行进入插入模式

插入模式切换为正常模式

目前处于插入模式,就只能一直输入文字,如果发现输错了字,想用光标键往回移动,将该字删除,可以先按一下「ESC」键转到正常模式再删除文字。当然,也可以直接删除。

正常模式切换到末行模式

  • 「shift + ;」其实就是输入「 : 」

退出vim及保存文件

在正常模式下,先进入末行模式输入:

  • w:保存文件,但不退出
  • q:退出
  • wq!:强制保存并退出

vim正常模式命令集

移动光标

  • vim可以用键盘上的上下左右键来控制光标,但正规的vim是用小写的字母「h」、「j」、「k」、 「l」、分别控制光标左、下、上、右移动一格
  • 按「G」:移动到文章最后
  • 按「gg」:移动到文章开头
  • 按「$」:移动到所在行的行尾
  • 按「^」:移动到所在行的行首
  • 按「w」:光标跳到下一个字符串的开头
  • 按「b」:光标回到上个字符串的开头

删除文字

  • 「x」:每按一次删除光标所在位置的一个字符
  • 「# x」:删除光标所在位置后面(包含自己)的 # 个字符
  • 「dd」:删除光标所在行
  • 「#dd」:从光标位置开始删除 # 行

复制

  • 「yy」:复制光标所在行到缓冲区
  • 「yw」:复制光标所在位置到所在字符串末尾的字符到缓冲区
  • 「#yw」:复制#个字到缓冲区
  • 「p」:将缓冲区内的字符贴到光标所在位置。注意:所有与"y"有关的复制命令都必须与"p"配合才能完成复制与粘贴功能

替换

  • 「r」:替换光标所在处的字符
  • 「R」:替换光标所到之处的字符,直到按下「ESC」键为止。

撤销上一次操作

  • 「u」:如果您误执行一个命令,可以马上按下「u」,回到上一个操作。按多次"u"可以执行多次回复。
  • 「ctrl + r」: 撤销的恢复*(撤销你的撤销)*

更改

  • 「cw」:更改光标所在处的字符到字符串尾部,并进入插入模式

跳至指定行

  • 「ctrl」+「g」:列出光标所在行的行号。
  • 「#G」:光标移动至第 # 行行首,例如,「15G」,表示移动光标至文章的第15行行首。

vim末行模式命令集

在使用末行模式之前,请记住先按「ESC」键确定已经处于正常模式,再按「:」冒号即可进入末行模式。

列出行号

  • 「set nu」: 输入「set nu」后,会在文件中的每一行前面列出行号

跳到文件中的某一行

  • 「#」:「#」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行行首

查找字符

  • 「/关键字」: 先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按 「n」会往后寻找到您要的关键字为止。
  • 「?关键字」:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直 按「n」会往前寻找到您要的关键字为止。

保存文件

  • 「w」: 在冒号输入字母「w」就可以将文件保存起来

离开vim

  • 「q」:按「q」就是退出,如果无法离开vim,可以在「q」后跟一个「!」强制离开vim。
  • 「wq」:一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件。

Linux项目自动化构建工具make/Makefile

  1. 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
  2. makefile带来的好处就是------"自动化编译",一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
  3. make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一 种在工程方面的编译方法。
  4. make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建

实例

比如我们有一个code.c文件要将它预处理、编译、汇编为 .o文件可以在Makefile里输入:

cpp 复制代码
code:code.o
    gcc -o code code.o
code.o:code.s
    gcc -c code.o code.s
code.s:code.i
    gcc -S code.s code.i
code.i:code.c
    gcc -E code.i code.c

上面的意思就是将code.c文件处理成可执行文件,code依赖code.o这是依赖关系,第二行的命令就是依赖方法

make是如何工作的,在默认的方式下,也就是我们只输入make命令。

  1. make会在当前目录下找名字叫"Makefile"或"makefile"的文件。
  2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到"code"这个文件, 并把这个文件作为最终的目标文件。
  3. 如果code文件不存在,或是code所依赖的后面的code.o文件的文件修改时间要比code这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成hello这个文件。
  4. 如果code所依赖的code.o文件不存在,那么make会在当前文件中找目标为code.o文件的依赖性,如果找到则再根据那一个规则生成code.o文件。(这有点像一个堆栈的过程)
  5. 当然,你的C文件和H文件是存在的啦,于是make会生成 code.o 文件,然后再用 code.o 文件声明make的终极任务,也就是执行文件code了。
  6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
  7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错, 而对于所定义的命令的错误,或是编译不成功,make根本不管。
  8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起, 我就不工作啦。

项目清理

  • 像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行, 不过,我们可以显示要make执行。即命令------"make clean",以此来清除所有的目标文件,以便重新编译。
  • 但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。
  • 由于伪目标不对应实际文件,make 在处理伪目标时不会根据文件的存在与否、时间戳等来判断是否需要执行相关操作,而是只要在命令行中指定了要执行该伪目标,make 就会执行与之关联的命令序列。
cpp 复制代码
.PHONY:
clean:
    @rm -f *.i *.s *.o
    @echo "remove"

ps:命令前面加@在执行的时候就不会回显

进度条小程序

第一版:没有和网络联系起来

cpp 复制代码
#include "process.h"
#include <string.h>
#include <unistd.h>
#define style '#'

void process_v1()
{
	char buff[101] = { '0' };
	const char* stat = "|/-\\";
	int len = strlen(stat);
	for(int i = 0; i < 101; i++)
	{
		printf("[%-100s][%d%][%c]\r",buff,i,stat[i%len]);
		fflush(stdout);
		buff[i] = style;
		usleep(50000);
		
	}
	printf("\n");
}

第二版:

cpp 复制代码
#include<stdio.h>

void process_v2(double total, double cur)
{
	char buff[101] = { '0' };
	const char* lable = "|/-\\";
	int len = strlen(lable);

	int num =(int)(cur*100/total);
	for(int i = 0; i < num; i++)
	{
		buff[i] = '#';
	}
	double rate = (cur*100)/total;
	static count = 0;
	printf("\033[32m[%-100s][%.1f%%][%c]\033[0m\r",buff,rate,lable[count%len]);

	count++;	
	fflush(stdout);
}


int main()
{
	int t = 1024;
	int ad = 0;
	while(ad <= 1024)
	{
		process_v2(t,ad);
		ad++;
		usleep(5000);// 模拟网络下载
	}
	printf("\033[32m\n\rcomplete!!!\033[0m\n");
	return 0;
}

本期博客到这里就结束了,如果有什么错误,欢迎指出,如果对你有帮助,请点个赞,谢谢!

相关推荐
梅秃头1 分钟前
CentOS 8修改Linux配置文件指定属性的值
linux·运维·服务器
一个小坑货4 分钟前
CentOS9 Stream上安装Edge浏览器
linux·centos
我是如子啊8 分钟前
【UBuntu20 配置usb网卡】 记录Ubuntu20配置usb网卡(特别是建立热点)
linux·网卡·教程·ubuntu20.04·wifi热点·ap·usb网卡
sdau_blue15 分钟前
pycharm远程服务器Linux下解决cannot connect to X server问题
linux·运维·服务器
CP-DD21 分钟前
linux 高级 I/O
linux
baidu_3755288123 分钟前
温度传感器 芯片ms5607 linux 驱动代码
linux·运维·服务器
言之。23 分钟前
linux 删除当前目录下修改时间超过1天的文件
linux·运维·服务器
陌夏微秋25 分钟前
Linux_01 Linux 系统文件
linux·运维·arm开发
江池俊35 分钟前
Linux上本地部署KubeSphere与cpolar实现远程管理和监控集群
linux·运维·服务器
茶馆大橘1 小时前
Docker部署学习
linux·运维·学习·docker·容器