Linux快速入手系列二( 文本处理 )

文本编辑神器-Vim

vim的三种操作模式

vim有三种操作模式,分别是命令模式(Command mode)、输入模式(Insert mode)和底线命令模式(Last line mode)。

三种模式切换快捷键:

模式 快捷键
命令模式 ESC
输入模式 i 或 a
底线命令模式 :
  • 命令模式

    在命令模式中控制光标移动和输入命令,可对文本进行复制、粘贴、删除和查找等工作。

    使用命令vim filename后进入编辑器视图后,默认模式就是命令模式,此时敲击键盘字母会被识别为一个命令,例如在键盘上连续敲击两次d,就会删除光标所在行。

    以下是在命令模式中常用的快捷操作:

操作 快捷键
光标左移 h
光标右移 l(小写L)
光标上移 k
光标下移 j
光标移动到下一个单词 w
光标移动到上一个单词 b
移动游标到第n行 nG
移动游标到第一行 gg
移动游标到最后一行 G
快速回到上一次光标所在位置 Ctrl+o
删除当前字符 x
删除前一个字符 X
删除整行 dd
删除一个单词 dw或daw
删除至行尾 d$或D
删除至行首 d^
删除到文档末尾 dG
删除至文档首部 d1G
删除n行 ndd
删除n个连续字符 nx
将光标所在位置字母变成大写或小写 ~
复制游标所在的整行 yy(3yy表示复制3行)
粘贴至光标后(下) p
粘贴至光标前(上) P
剪切 dd
交换上下行 ddp
替换整行,即删除游标所在行并进入插入模式 cc
撤销一次或n次操作 u{n}
撤销当前行的所有修改 U
恢复撤销操作 Ctrl+r
整行将向右缩进 >>
整行将向左退回 <<
若档案没有更动,则不储存离开,若档案已经被更动过,则储存后离开 ZZ
  • 输入模式

    在命令模式下按i或a键就进入了输入模式,在输入模式下,您可以正常的使用键盘按键对文本进行插入和删除等操作。

  • 底线命令模式

    在命令模式下按:键就进入了底线命令模式,在底线命令模式中可以输入单个或多个字符的命令。

    以下是底线命令模式中常用的快捷操作:

操作 命令
保存 :w
退出 :q
保存并退出 :wq(:wq!表示强制保存退出)
将文件另存为其他文件名 :w new_filename
显示行号 :set nu
取消行号 :set nonu
使本行内容居中 :ce
使本行文本靠右 :ri
使本行内容靠左 :le
向光标之下寻找一个名称为word的字符串 :/word
向光标之上寻找一个字符串名称为word的字符串 :?word
重复前一个搜寻的动作 :n
从第一行到最后一行寻找word1字符串,并将该字符串取代为word2 :1,$s/word1/word2/g:%s/word1/word2/g

使用示例

在本示例将使用vim在文本文件中写入一首唐诗。

  • 新建一个文件并进入vim命令模式。

    vim 静夜思.txt
    
  • 按下i进入输入模式,输入 静夜思

  • 按下ECS键回到命令模式,并输入底线命令:ce,使诗名居中。

  • 按下o键 换行同时进入输入模式,输入第一行诗。

                                         静夜思
                                窗前明月光,疑是地上霜.
    
  • 按下ECS键回到命令模式,并输入底线命令:ce,使第一行诗居中。

  • 按下o键换行并进入输入模式,输入第二行诗。

  • 按下ECS键回到命令模式,并输入底线命令:ce,使第二行诗居中。

  • 在命令模式中执行底线命令:wq离开vim。

文本文件查看命令

cat(常用)

命令描述:cat命令用于查看内容较少的纯文本文件。

命令格式:cat [选项] [文件]

命令参数说明:

参数 说明
-n或--number 显示行号
-b或--number-nonblank 显示行号,但是不对空白行进行编号
-s或--squeeze-blank 当遇到有连续两行以上的空白行,只显示一行的空白行

命令使用示例:

  • 将一个自增序列写入test.txt文件中。

    for i in $(seq 1 10); do echo $i >> test.txt ; done
    
  • 查看文件内容。

    [root@sb6a ~]# cat test.txt
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
  • 将文件内容清空。

    cat /dev/null > test.txt
    
  • 再次检查文件内容,结果内容为空。

more(常用)

命令描述:more命令从前向后分页显示文件内容。

常用操作命令:

操作 作用
Enter 向下n行,n需要定义,默认为1行
Ctrl+F或空格键(Space) 向下滚动一页
Ctrl+B 向上滚动一页
= 输出当前行的行号
!命令 调用Shell执行命令
q 退出more

命令使用示例:

  • 从第20行开始分页查看系统日志文件/var/log/messages。

    [root@sb6a ~]# more +20 /var/log/messages
    Apr 26 16:02:02 sb6a systemd: Stopped target Login Prompts.
    Apr 26 16:02:02 sb6a systemd: Stopping Serial Getty on ttyS0...
    Apr 26 16:02:02 sb6a systemd: Stopping Getty on tty1...
    Apr 26 16:02:02 sb6a systemd: Stopped Execute cloud user/final scripts.
    Apr 26 16:02:02 sb6a systemd: Stopped Apply the settings specified in cloud-config.
    Apr 26 16:02:02 sb6a systemd: Stopped target Cloud-config availability.
    Apr 26 16:02:02 sb6a systemd: Stopping Command Scheduler...
    Apr 26 16:02:02 sb6a systemd: Stopping Session 3 of user root.
    Apr 26 16:02:02 sb6a systemd: Stopping Session 2 of user root.
    Apr 26 16:02:02 sb6a systemd: Stopped Daily Cleanup of Temporary Directories.
    Apr 26 16:02:02 sb6a systemd: Stopping Job spooling tools...
    Apr 26 16:02:02 sb6a systemd: Stopped Authorization Manager.
    Apr 26 16:02:02 sb6a systemd: Stopped NTP client/server.
    Apr 26 16:02:02 sb6a systemd: Stopped aliyun-assist.
    Apr 26 16:02:02 sb6a systemd: Stopped OpenSSH server daemon.
    Apr 26 16:02:02 sb6a systemd: Stopped Job spooling tools.
    Apr 26 16:02:02 sb6a systemd: Stopped Command Scheduler.
    Apr 26 16:02:02 sb6a systemd: Stopped Serial Getty on ttyS0.
    Apr 26 16:02:02 sb6a systemd: Stopped Getty on tty1.
    Apr 26 16:02:02 sb6a systemd: Stopped Session 2 of user root.
    Apr 26 16:02:02 sb6a systemd: Stopped System Logging Service.
    Apr 26 16:02:02 sb6a systemd: Stopped Session 3 of user root.
    Apr 26 16:02:02 sb6a systemd: Removed slice User Slice of root.
    Apr 26 16:02:02 sb6a systemd: Stopping Login Service...
    Apr 26 16:02:02 sb6a systemd: Starting Show Plymouth Power Off Screen...
    Apr 26 16:02:02 sb6a systemd: Removed slice system-getty.slice.
    Apr 26 16:02:02 sb6a systemd: Removed slice system-serial\x2dgetty.slice.
    Apr 26 16:02:02 sb6a systemd: Stopping Permit User Sessions...
    Apr 26 16:02:02 sb6a systemd: Stopped Permit User Sessions.
    --More--(4%)
    

less(常用)

命令描述:less命令可以对文件或其它输出进行分页显示,与moe命令相似,但使用 less 可以随意浏览文件,而 more 仅能向前移动,却不能向后移动。

命令格式:less [参数] 文件

命令参数说明:

参数 说明
-e 当文件显示结束后,自动离开
-m 显示类似more命令的百分比
-N 显示每行的行号
-s 显示连续空行为一行

命令常用操作:

快捷键 说明
/字符串 向下搜索字符串
?字符串 向上搜索字符串
n 重复前一个搜索
N 反向重复前一个搜索
b或pageup 向上翻一页
空格键或pagedown 向下翻一页
u 向前翻半页
d 向后翻半页
y 向前滚动一行
回车键 向后滚动一行
q 退出less命令

命令使用示例:

查看命令历史使用记录并通过less分页显示。

history | less

head(常用)

命令描述:head命令用于查看文件开头指定行数的内容。

命令格式:head [参数] [文件]

命令参数说明:

参数 说明
-n [行数] 显示开头指定行的文件内容,默认为10
-c [字符数] 显示开头指定个数的字符数
-q 不显示文件名字信息,适用于多个文件,多文件时默认会显示文件名

命令使用示例:

查看/etc/passwd文件的前5行内容。

head -5 /etc/passwd

tail(常用)

命令描述:tail命令用于查看文档的后N行或持续刷新内容。

命令格式:tail [参数] [文件]

命令参数说明:

参数 说明
-f 显示文件最新追加的内容
-q 当有多个文件参数时,不输出各个文件名
-v 当有多个文件参数时,总是输出各个文件名
-c [字节数] 显示文件的尾部n个字节内容
-n [行数] 显示文件的尾部n行内容

命令使用示例:

查看/var/log/messages系统日志文件的最新10行,并保持实时刷新。

tail -f -n 10 /var/log/messages

ctrl+c键退出文本实时查看界面。

stat

命令描述:用来显示文件的详细信息,包括inode、atime、mtime、ctime等。

命令使用示例:

查看/etc/passwd文件的详细信息。

[root@sb6a ~]# stat /etc/passwd
  File: ‘/etc/passwd’
  Size: 1000            Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 1059598     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-06-04 20:50:08.717697646 +0800
Modify: 2020-06-04 20:50:08.703697160 +0800
Change: 2020-06-04 20:50:08.704697195 +0800
 Birth: -

wc

命令描述:wc命令用于统计指定文本的行数、字数、字节数。

命令格式:wc [参数] [文件]

命令参数说明:

参数 说明
-l 只显示行数
-w 只显示单词数
-c 只显示字节数

命令使用示例:

统计/etc/passwd文件的行数。

[root@sb6a ~]# wc -l /etc/passwd
23 /etc/passwd

file

命令描述: file命令用于辨识文件类型。

命令格式:file [参数] [文件]

命令参数说明:

参数 说明
-b 列出辨识结果时,不显示文件名称
-c 详细显示指令执行过程,便于排错或分析程序执行的情形
-f [文件] 指定名称文件,其内容有一个或多个文件名称时,让file依序辨识这些文件,格式为每列一个文件名称
-L 直接显示符号连接所指向的文件类别

命令使用示例:

查看/var/log/messages文件的文件类型。

[root@sb6a ~]# file /var/log/messages
/var/log/messages: UTF-8 Unicode text

diff(常用)

命令描述:diff命令用于比较文件的差异。

命令使用示例:

  • 构造两个相似的文件

    echo -e '第一行\n第二行\n我是log1第3行\n第四行\n第五行\n第六行' > 1.log
    echo -e '第一行\n第二行\n我是log2第3行\n第四行' > 2.log
    
  • 分别查看两个文件

    [root@sb6a ~]# echo -e '第一行\n第二行\n我是log1第3行\n第四行\n第五行\n第六行' > 1.log
    [root@sb6a ~]# echo -e '第一行\n第二行\n我是log2第3行\n第四行' > 2.log
    [root@sb6a ~]# cat 1.log
    第一行
    第二行
    我是log1第3行
    第四行
    第五行
    第六行
    [root@sb6a ~]# cat 2.log
    第一行
    第二行
    我是log2第3行
    第四行
    
  • 使用diff查看两个文件的差异

    [root@sb6a ~]# diff 1.log 2.log
    3c3
    < 我是log1第3行
    ---
    > 我是log2第3行
    5,6d4
    < 第五行
    < 第六行
    

    对比结果中的 3c3 表示两个文件在第3行有不同,5,6d4 表示 2.log 文件相比 1.log 文件在第 4 行处开始少了 1.log 文件的第5和第6行。

文本文件处理命令

grep(常用)

命令描述:grep命令用于查找文件里符合条件的字符串。

grep全称是Global Regular Expression Print,表示全局正则表达式版本,它能使用正则表达式搜索文本,并把匹配的行打印出来。

在Shell脚本中,grep通过返回一个状态值来表示搜索的状态:

  • 0:匹配成功。
  • 1:匹配失败。
  • 2:搜索的文件不存在。

命令格式:grep [参数] [正则表达式] [文件]

命令常用参数说明:

参数 说明
-c或--count 计算符合样式的列数
-d recurse或-r 指定要查找的是目录而非文件
-e [范本样式] 指定字符串做为查找文件内容的样式
-E 或 --extended-regexp 将样式为延伸的正则表达式来使用
-F 或 --fixed-regexp 将样式视为固定字符串的列表
-G 或 --basic-regexp 将样式视为普通的表示法来使用
-i 或 --ignore-case 忽略字符大小写的差别
-n 或 --line-number 在显示符合样式的那一行之前,标示出该行的列数编号
-v 或 --revert-match 显示不包含匹配文本的所有行

命令使用示例:

  • 查看sshd服务配置文件中监听端口配置所在行编号。

    [root@sb6a ~]# grep -n Port /etc/ssh/ssh_config
    41:#   Port 22
    
  • 查询字符串在文本中出现的行数。

    [root@sb6a ~]# grep -c localhost /etc/hosts
    2
    
    
  • 反向查找,不显示符合条件的行。

    [root@sb6a ~]# ps -ef | grep sshd
    root       985     1  0 20:45 ?        00:00:00 /usr/sbin/sshd -D
    root      1390   985  0 20:46 ?        00:00:00 sshd: root@pts/0
    root      1538   985  0 21:04 ?        00:00:00 sshd: root@pts/1
    root     11263  1541  0 21:27 pts/1    00:00:00 grep --color=auto sshd
    
    [root@sb6a ~]# ps -ef | grep -v grep | grep sshd
    root       985     1  0 20:45 ?        00:00:00 /usr/sbin/sshd -D
    root      1390   985  0 20:46 ?        00:00:00 sshd: root@pts/0
    root      1538   985  0 21:04 ?        00:00:00 sshd: root@pts/1
    
    
  • 以递归的方式查找目录下含有关键字的文件。

    [root@sb6a ~]# grep -r *.sh /etc
    Binary file /etc/udev/hwdb.bin matches
    /etc/NetworkManager/dispatcher.d/11-dhclient:    for f in $ETCDIR/dhclient.d/*.sh; do
    /etc/bashrc:    for i in /etc/profile.d/*.sh; do
    /etc/profile:for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
    
    
  • 使用正则表达式匹配httpd配置文件中异常状态码响应的相关配置。

    [root@sb6a ~]# grep 'ntp[0-9].aliyun.com' /etc/ntp.conf
    restrict ntp1.aliyun.com nomodify notrap nopeer noquery
    restrict ntp2.aliyun.com nomodify notrap nopeer noquery
    restrict ntp3.aliyun.com nomodify notrap nopeer noquery
    restrict ntp4.aliyun.com nomodify notrap nopeer noquery
    restrict ntp5.aliyun.com nomodify notrap nopeer noquery
    restrict ntp6.aliyun.com nomodify notrap nopeer noquery
    server ntp1.aliyun.com iburst minpoll 4 maxpoll 10
    server ntp2.aliyun.com iburst minpoll 4 maxpoll 10
    server ntp3.aliyun.com iburst minpoll 4 maxpoll 10
    server ntp4.aliyun.com iburst minpoll 4 maxpoll 10
    server ntp5.aliyun.com iburst minpoll 4 maxpoll 10
    server ntp6.aliyun.com iburst minpoll 4 maxpoll 10
    
    

sed(常用)

命令描述:sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用。

  1. 处理时,把当前处理的行存储在临时缓冲区中,称为模式空间(pattern space)。

  2. 接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。

  3. 接着处理下一行,这样不断重复,直到文件末尾。

注意:

  • sed命令不会修改原文件,例如删除命令只表示某些行不打印输出,而不是从原文件中删去。
  • 如果要改变源文件,需要使用-i选项。

命令格式:sed [参数] [动作] [文件]

参数说明:

参数 说明
-e [script] 执行多个script
-f [script文件] 执行指定script文件
-n 仅显示script处理后的结果
-i 输出到原文件,静默执行(修改原文件)

动作说明:

动作 说明
a 在行后面增加内容
c 替换行
d 删除行
i 在行前面插入
p 打印相关的行
s 替换内容

命令使用示例:

  • 删除第3行到最后一行内容。

    [root@sb6a ~]# sed '3,$d' /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    
    
  • 在最后一行新增行。

    [root@sb6a ~]# sed '$a admin:x:1000:1000:admin:/home/admin:/bin/bash' /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    nobody:x:99:99:Nobody:/:/sbin/nologin
    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    dbus:x:81:81:System message bus:/:/sbin/nologin
    polkitd:x:999:998:User for polkitd:/:/sbin/nologin
    sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
    postfix:x:89:89::/var/spool/postfix:/sbin/nologin
    chrony:x:998:996::/var/lib/chrony:/sbin/nologin
    nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
    tcpdump:x:72:72::/:/sbin/nologin
    test:x:1000:1000::/home/test:/bin/bash
    admin:x:1001:1001::/home/admin:/bin/bash
    admin:x:1000:1000:admin:/home/admin:/bin/bash
    
    
  • 替换内容。

    [root@sb6a ~]# sed 's/SELINUX=disabled/SELINUX=enforcing/' /etc/selinux/config
    
    # This file controls the state of SELinux on the system.
    # SELINUX= can take one of these three values:
    #     enforcing - SELinux security policy is enforced.
    #     permissive - SELinux prints warnings instead of enforcing.
    #     disabled - No SELinux policy is loaded.
    SELINUX=enforcing
    # SELINUXTYPE= can take one of three values:
    #     targeted - Targeted processes are protected,
    #     minimum - Modification of targeted policy. Only selected processes are protected.
    #     mls - Multi Level Security protection.
    SELINUXTYPE=targeted
    
    
  • 替换行。

    [root@sb6a ~]# sed '1c abcdefg' /etc/passwd
    abcdefg
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    operator:x:11:0:operator:/root:/sbin/nologin
    games:x:12:100:games:/usr/games:/sbin/nologin
    ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    nobody:x:99:99:Nobody:/:/sbin/nologin
    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    dbus:x:81:81:System message bus:/:/sbin/nologin
    polkitd:x:999:998:User for polkitd:/:/sbin/nologin
    sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
    postfix:x:89:89::/var/spool/postfix:/sbin/nologin
    chrony:x:998:996::/var/lib/chrony:/sbin/nologin
    nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
    tcpdump:x:72:72::/:/sbin/nologin
    test:x:1000:1000::/home/test:/bin/bash
    admin:x:1001:1001::/home/admin:/bin/bash
    
    

awk(常用)

命令描述:和 sed 命令类似,awk 命令也是逐行扫描文件(从第 1 行到最后一行),寻找含有目标文本的行,如果匹配成功,则会在该行上执行用户想要的操作;反之,则不对行做任何处理。

命令格式:awk [参数] [脚本] [文件]

参数说明:

参数 说明
-F fs 指定以fs作为输入行的分隔符,awk 命令默认分隔符为空格或制表符
-f file 读取awk脚本
-v val=val 在执行处理过程之前,设置一个变量var,并给其设置初始值为val

内置变量:

变量 用途
FS 字段分隔符
$n 指定分隔的第n个字段,如$1、$3分别表示第1、第三列
$0 当前读入的整行文本内容
NF 记录当前处理行的字段个数(列数)
NR 记录当前已读入的行数
FNR 当前行在源文件中的行号

awk中还可以指定脚本命令的运行时机。默认情况下,awk会从输入中读取一行文本,然后针对该行的数据执行程序脚本,但有时可能需要在处理数据前运行一些脚本命令,这就需要使用BEGIN关键字,BEGIN会在awsk读取数据前强制执行该关键字后指定的脚本命令。

和BEGIN关键字相对应,END关键字允许我们指定一些脚本命令,awk会在读完数据后执行它们。

命令使用示例:

  • 查看本机IP地址。

    [root@sb6a ~]# ifconfig eth0 |awk '/inet/{print $2}'
    172.16.1.203
    
    
  • 查看本机剩余磁盘容量。

    [root@sb6a ~]# df -h | awk '/\/$/{print $4}'
    36G
    
    
  • 关闭指定服务的所有的进程。

    ps -ef | grep httpd | awk {'print $2'} | xargs kill -9
    
    

Reference

阿里云开发者社区