linux文本处理工具

Posted 向往自由的独行者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux文本处理工具相关的知识,希望对你有一定的参考价值。

linux文本处理工具


1. 文本查看工具

1.1 cat命令详解

cat命令主要功能是将一个或多个文件或标准输入连接,并输出至标准输出。通常用户查看文件内容。

cat命令的语法如下:

cat [OPTION]... [FILE]...

cat常用选项如下:

选项 说明
-A 显示文本中所有的特殊符号
-n 显示文本时对所有行加行号
-b 显示文本时对仅所有非空行加行号
-s 合并相邻的空行为一行

cat命令的常见用法如下:

[root@xuzhichao ~]# echo -e "1\\n\\n\\n2\\n\\n3\\n4" > file1
[root@xuzhichao ~]# cat file1
1


2

3
4

#显示行号
[root@xuzhichao ~]# cat -n file1
     1	1
     2	
     3	
     4	2
     5	
     6	3
     7	4
     
#仅对非空行显示行号     
[root@xuzhichao ~]# cat -b file1
     1	1


     2	2
    
     3	3
     4	4

#压缩所有空行为一行
[root@xuzhichao ~]# cat -sn file1
     1	1
     2	
     3	2
     4	
     5	3
     6	4

#显示所有的特殊字符
[root@xuzhichao ~]# cat -A file1
1$           <==$代表换行
^I^I$        <==^I代表tab键
$
2$
  $          <==空代表空格键
3$
4$
  • tac命令:该命令和cat命令功能类似,按照行的顺序倒序显示。

    - [root@xuzhichao ~]# echo -e "123 \\n abc" > file1
      [root@xuzhichao ~]# tac file1
       abc
      123 
    
  • rev命令:用于将同一行的内容前后倒序显示。

    [root@xuzhichao ~]# cat file1
    123 
     abc
    [root@xuzhichao ~]# rev file1
     321
    cba 
    

1.2 more和less命令详解

more和less命令用于打开一个较长的文件时,进行分页显示。

more和less命令的用法大致相同,使用该命令时会进入一个命令窗口,该窗口下有如下快捷键:

快捷键 说明
回车键 文件下移一行显示
空格键 文件向下翻一页
b 向上翻一页
/string 向下搜索内容string
n 配合搜索功能实现同向的下一个查找
退出分页显示

less命令还有一些独有的快捷键

快捷键 说明
?string 向上搜索内容string
N 配合搜索功能实现逆向的下一个查找
g 移动到行首
G 移动到行尾

而且more命令在移动到最后一行后会自动退出more命令。而less命令不会自动退出,因此less命令比more命令更加的灵活。

more或less经常用于结合管道分页显示前一个命令的内容,主要用法如下:

[root@xuzhichao ~]# ls /etc/ | more

1.3 head和tail命令详解

  • head命令:用于显示文件的前几行内容,主要选项如下:

    选项 说明
    -n NUM 指定显示前NUM行的内容,默认显示10行
    -c NUM 显示一行前NUM个字节的内容

    注意:以上参数中NUM值若为负数,则表示从开头到倒数第NUM行或倒数第NUM个字节。

    #默认显示头部10行内容
    [root@xuzhichao ~]# head /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
    
    #显示前三行内容
    [root@xuzhichao ~]# head -n 3 /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
    
    #从开头显示到倒数第三行内容
    [root@xuzhichao ~]# seq 10 | head -n -3
    1
    2
    3
    4
    5
    6
    7
    
    #显示前三个字符
    [root@xuzhichao ~]# echo "abcdefg" | head -c 3
    abc[root@xuzhichao ~]# 
    
    #显示从开头到倒数第三个字节的内容
    [root@xuzhichao ~]# echo "abcdefg" | head -c -3
    abcde[root@xuzhichao ~]# 
    
  • tail命令:用于显示文件的最后几行内容,主要选项如下:

    选项 说明
    -n NUM 指定显示后NUM行的内容,默认显示10行
    -c NUM 显示一行后NUM个字节的内容
    -f 动态跟踪文件尾部内容的变化,一般用于查看日志文件

    注意:NUM前使用“+”表示除了前NUM行内容不输出,后面的内容全部输出

    tail用法如下:

    [root@xuzhichao ~]# seq 10 | tail -n 3
    8
    9
    10
    [root@xuzhichao ~]# seq 10 | tail -n +3
    3
    4
    5
    6
    7
    8
    9
    10
    [root@xuzhichao ~]# echo "abcdefg" | tail -c 3   <==注意字符首部和尾部各有一个字节的数据^和$
    fg
    [root@xuzhichao ~]# echo "abcdefg" | tail -c +3
    cdefg
    
    #动态跟踪/var/log/messages文件的尾部变化,Ctrl+c退出
    [root@xuzhichao ~]# tail -f /var/log/messages
    
    

2. 简单文本处理工具

2.1 seq命令详解

seq命令用于以指定增量从首数开始打印数字到尾数,即产生从某个数到另外一个数之间的所有整数,并且可以对整数的格式、宽度、分割符号进行控制。

语法:
  [1] seq [选项]   尾数
  [2] seq [选项]   首数  尾数
  [3] seq [选项]   首数  增量 尾数

选项:
  -f, --format=格式
  -s, --separator=字符串,使用指定的字符串分割数字(默认使用个"\\n"分割)
  -w, --sequal-width  在列前添加0 使得宽度相同

seq命令的用法如下:

[root@xuzhichao ~]# seq 5
1
2
3
4
5
[root@xuzhichao ~]# seq -2 2 10
-2
0
2
4
6
8
10

#以空格作为输出的分隔符
[root@xuzhichao ~]# seq -s " " 5
1 2 3 4 5

#等宽输出97到100的数字,不足以0补齐
[root@xuzhichao ~]# seq -w 97 100
097
098
099
100

#格式化输出97耷100的数字,不足以空格补齐,%4g代表宽度为4的整数
[root@xuzhichao ~]# seq -f "%4g" 97 100
  97
  98
  99
 100
 
#格式化输出97耷100的数字,不足以0补齐
[root@xuzhichao ~]# seq -f "%004g" 97 100
0097
0098
0099
0100

2.2 tr命令详解

tr命令用户转换和删除字符,语法如下:

tr [OPTION]... SET1 [SET2]

主要选项如下:

选项 说明
-d 删除第一个字符集SET的字符
-c 取字符集SET的补集
-s 连续重复的字符显示未一个

tr命令的主要用法如下:

#示例一:不跟文件名会从标准输入中读取
[root@xuzhichao ~]# tr \'a-z\' \'A-Z\'
abc
ABC

#示例二:Windows和linux文件换行的转换。Windows使用回车(\\r)加换行(\\n)作为换行符,linux使用换行(\\n)作为换行符
[root@xuzhichao ~]# cat windows.txt -A
echo "M-DM-cM-:M-CM-#M-,windows"^M$
date^M$
[root@xuzhichao ~]# tr -d \'\\r\' < windows.txt > windows.linux.txt
[root@xuzhichao ~]# cat -A windows.linux.txt 
echo "M-DM-cM-:M-CM-#M-,windows"$
date$

#示例三:把df的输出中的空格转换为“:”
[root@xuzhichao ~]# df | tr -s \' \' \':\'
Filesystem:1K-blocks:Used:Available:Use%:Mounted:on
devtmpfs:914464:0:914464:0%:/dev
tmpfs:931520:0:931520:0%:/dev/shm
tmpfs:931520:10080:921440:2%:/run
tmpfs:931520:0:931520:0%:/sys/fs/cgroup
/dev/mapper/centos-root:52403200:4872008:47531192:10%:/
/dev/sda1:508580:171960:336620:34%:/boot
tmpfs:186304:0:186304:0%:/run/user/0

#示例四:将/etc/issue文件的中的所有小写字母转换为大写字母,然后保存在/data/test/issue.out中
[root@xuzhichao ~]# tr \'[[:lower:]]\' \'[[:upper:]]\' < /etc/issue > /data/test/issue.out

#示例五:把PATH变量的每个目录都变成独立的一行
[root@xuzhichao ~]# echo $PATH | tr \':\' \'\\n\'
/usr/lib64/qt-3.3/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/root/bin

2.3 cut命令详解

cut命令用于使用指定的分隔符对文件或标准输入的内容进行切割,然后对切割的内容按序号进行排序。

cut命令的语法为:

cut OPTION... [FILE]...

cut命令的选项如下:

选项 说明
-d 指定分隔符,默认分隔符为“TAB”
-f 显示指定字段的内容
-c 以字符为单位进行切割
--output-delimiter=STRING 指定输出内容的字段分隔符
--complement 取反
-c 以字节byte为单位进行切割

cut的主要用法如下:

#示例一:取df中磁盘的利用率
[root@xuzhichao ~]# df
Filesystem              1K-blocks    Used Available Use% Mounted on
devtmpfs                   914464       0    914464   0% /dev
tmpfs                      931520       0    931520   0% /dev/shm
tmpfs                      931520   10112    921408   2% /run
tmpfs                      931520       0    931520   0% /sys/fs/cgroup
/dev/mapper/centos-root  52403200 4871908  47531292  10% /
/dev/sda1                  508580  171960    336620  34% /boot
tmpfs  
[root@xuzhichao ~]# df | grep "^/dev/" | tr -s \' \' | cut -d \' \' -f 5 | tr -d %
10
34

#示例二:取ip地址
root@xuzhichao ~]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.20.17  netmask 255.255.255.0  broadcast 192.168.20.255
        inet6 fe80::9eb8:f0ae:83a6:97dd  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:17:6d:3e  txqueuelen 1000  (Ethernet)
        RX packets 24421  bytes 2172836 (2.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 9980  bytes 2705200 (2.5 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@xuzhichao ~]# ifconfig eth0 | grep "inet\\>" | tr -s \' \' | cut -d \' \' -f 3
192.168.20.17

#示例三:取/etc/passwd文件的用户名,UID,GID,描述信息。
[root@xuzhichao ~]# head -n 5 /etc/passwd | cut -d \':\' -f 1,3-5
root:0:0:root
bin:1:1:bin
daemon:2:2:daemon
adm:3:4:adm
lp:4:7:lp


#示例四:取/etc/passwd文件的用户名,UID,输出的分隔符为“====”。
[root@xuzhichao ~]# head -n 5 /etc/passwd | cut -d \':\' --output-delimiter="====" -f 1,3
root====0
bin====1
daemon====2
adm====3
lp====4

#示例五:按照字符切割
[root@xuzhichao ~]# cat > file1 <<EOF
> 1234567890
> 1234567890
> 1234567890
> EOF
[root@xuzhichao ~]# cut -c 2-6 file1
23456
23456
23456
[root@xuzhichao ~]# cut -c 2- file1  <==表示从第2个字符到本行末尾
234567890
234567890
234567890
[root@xuzhichao ~]# cut -c -9 file1  <==表示从本行开始到第9个字符
123456789
123456789
123456789

#示例六:按照字节切割
[root@xuzhichao ~]# cut -b 1-3 file1
123
123
123
[root@xuzhichao ~]# cut -b -3 file1
123
123
123

#取反,取出/etc/passwd中除密码外的其他所有字段
[root@xuzhichao ~]# head -n 5 /etc/passwd | cut -d \':\' --complement -f2
root:0:0:root:/root:/bin/bash
bin:1:1:bin:/bin:/sbin/nologin
daemon:2:2:daemon:/sbin:/sbin/nologin
adm:3:4:adm:/var/adm:/sbin/nologin
lp:4:7:lp:/var/spool/lpd:/sbin/nologin

2.4 paste命令详解

paste命令用于把两个文件合并为一个文件,默认以行为单位,默认以TAB作为分隔符。

paste主要选项如下:

选项 说明
-d 指定两个文件之间的分隔符
-s 先将文件的所有行合并成一行,再将合并后的文件按顺序分两行合并在一起

paste命令的用法如下:

[root@xuzhichao ~]# seq 5 > num1
[root@xuzhichao ~]# seq 6 10 > num2
[root@xuzhichao ~]# cat num1
1
2
3
4
5
[root@xuzhichao ~]# cat num2
6
7
8
9
10
[root@xuzhichao ~]# paste num1 num2
1	6
2	7
3	8
4	9
5	10
[root@xuzhichao ~]# paste -d ":" num1 num2
1:6
2:7
3:8
4:9
5:10
[root@xuzhichao ~]# paste -s -d ":" num1 num2
1:2:3:4:5
6:7:8:9:10
[root@xuzhichao ~]# paste -s num1 num2
1	2	3	4	5
6	7	8	9	10

2.5 wc命令详解

wc命令用于统计给定文件或标准输入的文本的行数,单词数,字节数,字符数。

wc的常用选项如下:

选项 说明
-l 只统计行数
-w 只统计单词数,单词是以空格作为分隔
-c 只统计字节数
-m 只统计字符数
-L 显示文件中最长的行

注意:一个英文字母或符号为一个字符,占一个字节;一个汉字为两个字符,占四个字节。

wc的用法如下:

#示例一:wc默认显示内容
[root@xuzhichao ~]# wc /etc/passwd
  38   74 1936 /etc/passwd           <==三个数字分别代表行数,单词数,字节数
  
#示例二:统计光盘中rpm包的个数
[root@xuzhichao ~]# ll /misc/cd/Packages/*.rpm | wc -l
10070

2.6 sort或uniq命令详解

  • sort命令用于按照一定的要求对文件的行或指定的字段进行排序,默认按照字母表顺序排序,数字排在字母前面。

    sort命令的选项如下

    选项 说明
    -n 按照数字大小排序
    -r 逆向排序
    -t 指定字段的分隔符
    -k 指定要排序字段的编号
    -u 删除输出的重复行
    -R 随机排序
    -f 忽略字符串中的大小写
  • uniq命令用于去重,还可以统计输出的次数,选项如下:

    选项 说明
    -c 显示连续且重复行的出现的次数
    -d 仅显示重复的行
    -u 仅显示不曾重复的行

    两个命令一般会结合使用,常见用法如下:

    #示例一:对/etc/passwd按照UID进行从小到大排序,取前三行
    [root@xuzhichao ~]# sort -n -t":" -k 3 /etc/passwd | head -n 3
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    
    #示例二:统计/etc/passwd文件中用户的shell类型,从大到小排序
    [root@xuzhichao ~]# cut -d: -f7 /etc/passwd |sort | uniq -c
          2 /bin/bash
          1 /bin/sync
          1 /sbin/halt
         33 /sbin/nologin
          1 /sbin/shutdown
    [root@xuzhichao ~]# cut -d: -f7 /etc/passwd |sort | uniq -c | sort -rn
         33 /sbin/nologin
          2 /bin/bash
          1 /sbin/shutdown
          1 /sbin/halt
          1 /bin/sync
          
    #示例三:对远程主机登陆次数的IP地址进行排序。
    [root@xuzhichao ~]# last
    root     pts/0        192.168.20.1     Wed May 19 20:58   still logged in   
    root     pts/1        192.168.20.1     Wed May 19 09:42   still logged in   
    root     pts/0        192.168.20.1     Tue May 18 23:18 - 11:41  (12:23)    
    root     pts/0        192.168.20.1     Tue May 18 17:01 - 23:18  (06:16)    
    reboot   system boot  3.10.0-1127.el7. Tue May 18 17:01 - 22:27 (1+05:26)   
    root     tty1                          Tue May 18 09:05 - 09:05  (00:00)    
    root     pts/2        192.168.20.1     Mon May 17 21:25 - 21:25  (00:00)    
    root     pts/1        192.168.20.1     Mon May 17 21:19 - crash  (19:41)    
    root     pts/2        192.168.20.1     Mon May 17 18:38 - 21:19  (02:41)    
    root     pts/0        192.168.20.1     Mon May 17 18:29 - crash  (22:31)    
    root     pts/0        192.168.20.1     Mon May 17 15:19 - 18:29  (03:10)    
    root     pts/1        192.168.20.1     Sun May 16 21:25 - 18:55  (21:30)    
    root     pts/0        192.168.20.1     Sun May 16 15:56 - 15:18  (23:22)    
    reboot   system boot  3.10.0-1127.el7. Sun May 16 15:51 - 22:27 (3+06:36)   
    root     pts/0        192.168.20.1     Sat May 15 22:51 - crash  (16:59)    
    reboot   system boot  3.10.0-1127.el7. Sat May 15 22:50 - 22:27 (3+23:37)   
    root     pts/1        192.168.20.1     Thu May 13 10:30 - crash (2+12:19)   
    root     pts/0        192.168.20.1     Wed May 12 21:35 - crash (3+01:15)   
    reboot   system boot  3.10.0-1127.el7. Wed May 12 21:30 - 22:27 (7+00:57)   
    root     pts/1        192.168.20.1     Tue May 11 22:35 - down   (00:53)    
    root     pts/0        192.168.20.1     Tue May 11 21:43 - down   (01:44)    
    reboot   system boot  3.10.0-1127.el7. Tue May 11 21:43 - 23:28  (01:44)    
    root     pts/1        192.168.20.1     Tue May 11 10:53 - down   (00:00)    
    root     pts/0        192.168.20.1     Mon May 10 17:16 - down   (17:36)    
    reboot   system boot  3.10.0-1127.el7. Mon May 10 17:16 - 10:53  (17:36)    
    root     tty1                          Thu May  6 18:34 - 18:34  (00:00)    
    root     pts/0        192.168.20.1     Thu May  6 12:22 - 18:34  (06:11)    
    root     pts/0        192.168.20.1     Wed May  5 21:17 - 12:22  (15:05)    
    root     pts/0        192.168.20.1     Wed May  5 21:14 - 21:16  (00:02)    
    reboot   system boot  3.10.0-1127.el7. Wed May  5 21:14 - 10:53 (5+13:39)   
    root     pts/0        192.168.20.1     Wed Apr 28 09:50 - crash (7+11:23)   
    root     pts/0        192.168.20.1     Wed Apr 28 09:48 - 09:50  (00:01)    
    root     pts/0        192.168.20.1     Wed Apr 28 09:28 - 09:48  (00:20)    
    root     tty1                          Wed Apr 28 09:27 - 00:06  (14:38)    
    reboot   system boot  3.10.0-1127.el7. Wed Apr 28 09:25 - 10:53 (13+01:27)  
    root     pts/0        192.168.20.1     Tue Nov  3 17:48 - down   (00:44)    
    root     pts/0        192.168.20.1     Tue Nov  3 17:47 - 17:48  (00:01)    
    root     pts/0        192.168.20.1     Tue Nov  3 17:42 - 17:47  (00:04)    
    root     pts/0        192.168.20.1     Tue Nov  3 17:37 - 17:42  (00:05)    
    root     tty1                          Tue Nov  3 17:28 - 18:33  (01:04)    
    reboot   system boot  3.10.0-1127.el7. Wed Nov  4 01:27 - 18:33  (-6:-54)   
    root     tty1                          Wed Nov  4 01:13 - 01:27  (00:14)    
    root     tty1                          Wed Nov  4 01:12 - 01:12  (00:00)    
    xu       pts/1        :0               Wed Nov  4 01:11 - down   (00:15)    
    xu       pts/0        :0               Wed Nov  4 01:11 - down   (00:16)    
    xu       :0           :0               Wed Nov  4 01:11 - down   (00:16)    
    reboot   system boot  3.10.0-1127.el7. Wed Nov  4 01:10 - 01:27  (00:16)    
    reboot   system boot  3.10.0-1127.el7. Wed Nov  4 01:06 - 01:27  (00:21)    
    reboot   system boot  3.10.0-1127.el7. Wed Nov  4 00:46 - 01:27  (00:40)    
    
    wtmp begins Wed Nov  4 00:46:56 2020
    [root@xuzhichao ~]# last | grep -E "(root|xu)" | tr -s " "|cut -d" " -f 3 | grep [0-9] | sort | uniq -c
         28 192.168.20.1
          3 :0
    

2.7 diff和patch命令详解

  • diff命令用于比较两个文件的不同之处。

    diff命令的使用示例如下:

    [root@xuzhichao ~]# cat f1
    1
    2
    a
    4
    5
    6
    7
    8
    9
    10
    [root@xuzhichao ~]# cat f2
    1
    2
    3
    4
    5
    6
    7
    
    [root@xuzhichao ~]# diff f1 f2
    3c3    <==表示两个文件在第三行有所不同
    < a    <==第一个文件为a
    ---
    > 3    <==第二个文件为3
    8,10d7  <==表示第一个文件比第二个文件多了第8行到第10行
    < 8     <==以下为多出的内容
    < 9
    < 10
    
    #-y选项为并排对比
    [root@xuzhichao ~]# diff -y f1 f2
    1								1
    2								2
    a							      |	3   <==“|”表示前后两个文件不同
    4								4
    5								5
    6								6
    7								7
    8							      <  <=="<"表示后面文件比前面少了此行内容;">"表示面文件比前面多了此行内容
    9							      <
    10							      <
    
    #-u为unified格式,一般用于生成补丁文件,和patch结合使用
    [root@xuzhichao ~]# diff -u f1 f2
    --- f1	2021-05-19 22:49:45.290554700 +0800
    +++ f2	2021-05-19 22:48:36.703099590 +0800
    @@ -1,10 +1,7 @@  <==“-”表示第一个文件,"+"表示第二个文件,“-1,10”表示第一个文件的1到10行;"+1,7"表示第二个文件的1到7行
     1
     2
    -a         <==“-”开头的行表示从第一个文件删除此行可以得到第二个文件
    +3         <==“+”开头的行表示从第一个文件增加此行可以得到第二个文件
     4
     5
     6
     7
    -8
    -9
    -10
    
  • patch命令:结合diff的输出unified格式信息和两个文件的任意一个,可以生成另外一个文件。

    #生成补丁文件
    [root@xuzhichao ~]# diff -u f1 f2 > diff.txt
    [root@xuzhichao ~]# cat f1
    1
    2
    a
    4
    5
    6
    7
    8
    9
    10
    [root@xuzhichao ~]# cat f2
    1
    2
    3
    4
    5
    6
    7
    #删除f2文件
    [root@xuzhichao ~]# rm -f f2
    #还原f2文件,-b表示备份f1文件为f1.orig文件,然后把f1文件内容还原为f2文件
    [root@xuzhichao ~]# patch -b f1 diff.txt 
    patching file f1
    [root@xuzhichao ~]# cat f1
    1
    2
    3
    4
    5
    6
    7
    [root@xuzhichao ~]# cat f1.orig 
    1
    2
    a
    4
    5
    6
    7
    8
    9
    10
    #删除f1文件也可以通过以上操作恢复f2
    

以上是关于linux文本处理工具的主要内容,如果未能解决你的问题,请参考以下文章

Linux篇 | 文本处理工具和正则表达式

Linux文本处理工具之grep sed简概

编程小技巧之 Linux 文本处理命令

Linux篇 | 文本处理工具和正则表达式

Linux 文本处理工具

linux文本处理工具