MENU

文章目录

Linux笔记13-文件过滤及内容处理

本文命令包括cattacmorelessheadtailtailfcutsplitpastesortjoinuniqwciconvdoc2unixdiffvimdiffrevtrodtee

文章篇幅较长,可结合右侧目录树跳转阅读。

1. cat:合并文件或查看文件内容

功能说明

此命令常用来显示单个文件内容,或者将几个文件内容连接起来一起显示,还可以从标准输入中读取内容并显示,生产环境常与重定向或追加符号配合使用。

语法格式

cat [option] [file]

选项说明

  • -n 从1开始对所有输出的内容按行编号
  • -b 和-n选项功能类似,但会忽略显示空白行行号
  • -s 当遇到有连续两行以上的空白行时,就替换为一行空白行
  • -A 等价于-vET三个选项的功能之和
  • -e 等价于-vE
  • -E 在每一行的行位显示$符号
  • -t 与-vT等价
  • -T 将Tab字符显示为^I
  • -v 除了LFD和TAB之外,使用^和M-引用

使用范例

  1. 执行如下完整的命令生成test.txt完整文件

    cat >test.txt<<EOF welcome to my blog. https://blog.leeyiding.com if you like my blog\'s contents,pls support me. bye! boys and girls.
    EOF

2. tac: 反向显示文件内容

功能说明

tac是cat的反向拼写,因此命令的功能是反向显示文件内容。

语法格式

tac [option] [file]

选项说明

  • -b 在行前而非行尾添加分隔标志
  • -r 将分隔标志作正则表达式来解析
  • -s 使用指定字符串代替换行作为分隔标志

使用范例

  1. 反向查看/etc/rc.local内容

    tac /etc/rc.local

3. more: 分页显示文件内容

功能说明

more命令的功能类似于cat,但cat命令是将整个文件的内容一次性的显示在屏幕上,而more命令则会一页一页地显示文件内容。

语法格式

more [option] [file]

选项说明

  • -num 指定屏幕显示大小为num行
  • +num 从行号num开始显示
  • -s 把连续的多个空行显示为一行
  • -p 不滚屏,而是清除整个屏幕,然后显示文本
  • -c 不滚屏,而是从每一行的顶部开始显示文本,每显示完一行,就清除这一行的剩余部分

交互式子命令说明

  • h或? 查看帮助
  • 空格键 向下滚动一屏
  • z 向下滚动一屏
  • Enter 向下显示1行
  • f 向下滚动一屏
  • b 返回上一屏
  • = 输出当前行的行号
  • / String 查找指定的文本
  • :f 输出文件名和当前的行号
  • v 调用vi编辑器
  • ! 调用shell,并执行命令
  • q 退出more

使用范例

  1. 显示定义的行数

    more -5 /etc/services
  2. 从指定的行数开始显示内容

    more +888 /etc/services
  3. 分页显示目录下的内容

    ls /etc | more -10

4. less: 分页显示文件内容

功能说明

less命令的基本功能类似于more命令,可以分页显示文件内容,但比more的功能更强大。less命令在读取文件内容时,并不是像more、vi命令一样,要一次性将整个文件加载之后再显示,而是会根据需要来加载文件的内容,这样打开文件的速度会更快。而且less命令支持[page up]、[page down]等按键的功能,可以通过该功能向前或向后翻看文件,这样更容易查看一个文件的内容。

语法格式

less [option] [file]

选项说明

  • -i 搜索时忽略大小写
  • -m 显示类似于more命令的进度百分比
  • -N 显示每行的行号
  • -s 将连续的空行压缩为一行显示
  • -e 当文件显示到结尾时自动退出文件,若不使用此选项就需要使用交互命令q退出less

交互式子命令说明

  • b 向前翻一页
  • 空格键 向后翻一页
  • u 向前翻半页
  • d 向后翻半页
  • y 向上滚动一行
  • 回车键 向下滚动一行
  • ↑ 向上滚动一行
  • ↓ 向下滚动一行
  • [page up] 向前翻一页
  • [page domn] 向后翻一页
  • /String 向下搜索字符串
  • ?String 向上搜索字符串
  • n 向后查找下一个匹配的文本
  • N 向前查找前一个匹配的文本
  • v 进入vi编辑界面
  • ! 调用Shell并执行命令
  • G 移动到最后一行
  • g 移动到第一行
  • h 显示帮助界面
  • q 退出less命令

使用范例

  1. 查看文件

    less /etc/services
  2. 显示行号

    less -N /etc/services
  3. 分页显示命令结果

    ls /etc | less

5. head:显示文件内容头部

功能说明

head命令用于显示文件内容头部,它默认输出文件的开头10行。

语法格式

head [option] [file]

选项说明

  • -n <行数> 指定显示的行数
  • -c <字节数> 指定显示的字节数
  • -q 不显示包含给定文件名的文件头
  • -v 总是显示包含给定文件名的文件头

使用范例

  1. 默认显示文件的前10行

    head /etc/passwd
  2. 显示文件的前n行

    head -n 5 /etc/passwd
    head -5 /etc/passwd
  3. 显示文件的前n个字节

    head -c 10 /etc/passwd
  4. 显示文件的最后n行或n个字节

    head -n -21 /etc/passwd
    head -c -1000 /etc/passwd
  5. 显示多个文件

    head -1 /etc/passwd /etc/gshadow
    head -qn 1 /etc/passwd /etc/gshadow

6. tail:显示文件尾部

功能说明

tail命令用于显示文件的尾部,它默认输出文件的最后10行。

语法格式

tail [option] [file]
tail [选项] [文件]

选项说明

  • -c <数目> 显示指定的字节数
  • -n <行数> 显示指定的行数
  • -f 实时输出文件变化后追加的数据
  • -F 功能等同于 -f --retry
  • --retry 不停地尝试打开文件,直到打开为止,与-f参数合用
  • --pid=进程号 在进程结束后自动退出tail命令,与-f参数合用
  • -s 秒数 N 监视文件变化的间隔秒数
  • -q 不显示包含指定文件名的文件头
  • -v 总是显示包含指定文件的文件头

使用范例

  1. 默认显示最后10行

    tail /etc/passwd
  2. 显示文件末尾5行的内容

    tail -n 5 /etc/passwd
  3. 从第15行开始显示文件

    tail -n +15 /etc/passwd
  4. 实时监视文件变化

    tail -f /application/nginx/logs/access.log
  5. 使用-F参数

    tail -f test.log   #使用-f参数,当文件不存在时会报错并退出命令
    tail -F test.log   #使用-F参数,当文件不存在时会报错,但还是会一直等待文件生成,不会退出命令

7. tailf:追踪日志文件

功能说明

tailf命令在工作中的主要使命就是跟踪日志文件,首先将默认输出日志文件的最后10行,然后实时地显示文件的增加内容。
tailf命令几乎等同于tail-f,与tail-f不同的是,如果文件不增长,那么它不会去访问磁盘文件,也不会更改文件的访问时间。

语法格式

tailf [option] [file]
tailf [选项] [文件]

选项说明

  • -n <行数> 显示指定的行数,默认显示十行

使用范例

追踪日志文件

tailf /application/nginx/logs/access.log

8. cut:从文本中提取一段文字并输出

功能说明

cut命令从文件的每一行剪切字节、字符或字段,并将这些字节、字符或字段输出至标准输出。

语法格式

cut [option] [file]
cut [选项] [文件]

选项说明

  • -b 以字节为单位进行分割
  • -n 取消分割多字节字符,与-b选项一起使用
  • -c 以字符为单位进行分割
  • -d 自定义分隔符,默认以tab为分隔符
  • -f 与选项-d一起使用,指定显示哪个区域
  • N 第N个字符、字节或字段
  • N- 从第N个字节、字节或字段开始直至行尾
  • N-M 从第N到第M(含第M)个字节、字符或字段
  • -M 从第1个到第M(含第M)个字节、字符或字段

使用范例

  1. 以字节为分隔符

    > cat test.txt
    I am superman
    
    > cut -b 3 test.txt #只输出第三个字节
    a
    
    > cut -b 3-5,10 test.txt #-b支持形如3-5的写法,而且多个定位之间用逗号隔开
    am r
    
    > cut -b -3 test.txt #-3表示从第一个字节到第三个字节
    I a
    
    > cut -b 3- test.txt #3-表示从第三个字节到行尾
    am superman
    
    > cut -b -3,3- test.txt #这种写法会输出整行,并且不会出现连续两个重叠的字母a
    I am superman
  2. 以字符为分隔符

    > cut -c 2-10 test.txt
     am super
     
    > cut -b 2-10 test.txt
     am super
     
     #本例使用选项-c和-b结果没有区别,是因为字母是单字节字符。如果提取中文,区别就看出来了。用选项-c则会以字符为单位,输出正常。而选项-b只会傻傻的以字节(8位二进制位)来计算,输出就是乱码。当遇到多字节字符时,可以使用-n选项,-n用于告诉cut不要将多字节字符拆开。
  3. 自定义分隔符

    cut -d : -f 1 /etc/passwd #选项-d指定以“:”为分隔符,-f指定显示第一个区域
    cut -d : -f 3-5 /etc/passwd #显示第-列到第5列

9. split:分割文件

功能说明

split命令可以按照指定的行数或者指定的文件大小分割文件

语法格式

split [option] [INPUT] [PREFIX]
split [选项] [输入文件] [输出文件名后缀]

选项说明

  • -b 指定分割后文件的最大字节数
  • -l 指定分割后文件的最大行数
  • -a 指定后缀长度,默认为2位字母
  • -a 使用数字后缀

使用范例

  1. 执行分割文件,以及指定后缀形式

    > wc -l inittab
    26 inittab
    
    > split -l 10 inittab new_ #每10行分割一次,文件名以new_开头
    > ls new_*
    new_aa new_ab new_ac
    > wc -l new_*
    10 new_aa
    10 new_ab
    6 new_ac
    26 total
    
    > split -l 10 -a inittab new2_ #参数-a指定后缀长度
    > wc -l new2_*
    10 new2_aaa
    10 new2_aab
    6 new2_aac
    26 total
    
    > split -l 10 -d inittab num_ #参数-d使用数字后缀
    > wc -l num_*
    10 num_00
    10 num_01
    6 num_02
    26 total
  2. 按大小分割文件

    > cp /sbin/lvm . #复制测试文件
    
    > ll -h
    total 1.3M
    -r-xr-xr-x 1 root root 1.3M Jan 1 00:00 lvm
    
    > split -b 500K -d lvm lvm_ #每500KB分割一次文件
    > ll -h
    total 2.6M
    -r-xr-xr-x 1 root root 1.3M Jan 1 00:00 lvm
    -rw-r--r-- 1 root root 500K Jan 1 00:00 lvm_00
    -rw-r--r-- 1 root root 500K Jan 1 00:00 lvm_01
    -rw-r--r-- 1 root root 308K Jan 1 00:00 lvm_02

10. paste:合并文件

功能说明

paste命令能将文件按照行与行进行合并,中间使用tab隔开

语法格式

paste [option] [file]
paste [选项] [文件]

选项说明

  • -d 指定合并的分隔符
  • -s 每个文件占用一行

使用范例

  1. 默认合并文件

    > cat test1 #准备好两个测试文件test1和test2
    1
    2
    3
    4
    5
    6
    
    > cat test2
    aaaa
    bbbbbbb
    ccccccccc
    
    eeeeeeeeeee
    gggggg
    
    > paste test1 test2 #两个文件按行进行合并
    1    aaaa
    2    bbbbbbb
    3    ccccccccc
    4    
    5    eeeeeeeeeee
    6    gggggg
  2. 通过-d选项可以指定分隔符

    > paste -d : test1 test2 #以“:”作为分隔符
    1:aaaa
    2:bbbbbbb
    3:ccccccccc
    4:
    5:eeeeeeeeeee
    6:gggggg
  3. 通过-s选项合并内容,使其成行

    > paste test1 #不接受任何参数,显示的内容如下所示
    1
    2
    3
    4
    5
    6
    
    > paste -s test1 #使用-s选项,将1列内容转换成1行
    1    2    3    4    5    6
    
    > paste -s test2
    aaaa    bbbbbbb    ccccccccc        eeeeeeeeeee    gggggg
    
    > paste -s test1 test2 #每个文件占用一行
    1    2    3    4    5    6
    aaaa    bbbbbbb    ccccccccc        eeeeeeeeeee    gggggg
  4. 与cut合并文本的方式进行对比

    > cat test1 test2 #cat是将两个文件按顺序前后合并
    1
    2
    3
    4
    5
    6
    aaaa
    bbbbbbb
    ccccccccc
    
    eeeeeeeeeee
    gggggg

生产案例

加入通过Shell脚本生产的账号密码如下所示

stu10309  #账号。
7f753cc3  #密码。
stu10312
636e026d
stu10315
18273b95
stu10318
d6908f61
stu10321
c441a16e
stu10324
28d5860d
stu10327
11ea966b

现在要求使用命令将上面的文本转换成下面SVN服务配置文件中的账号及密码格式

stu10309=7f753cc3  #格式:“账号=密码”。
stu10312=636e026d
stu10315=18273b95
stu10318=d6908f61
stu10321=c441a16e
stu10324=28d5860d
stu10327=11ea966b

提示:实现的思路就是将奇数行和偶数行用“=”(等号)连接成一行。

  1. 方法一:采用paste命令加-s参数实现。

    > paste -s test.txt
    stu10309    7f753cc3    stu10312    636e026d    stu10315    18273b95    stu10318    d6908f61    stu10321    c441a16e    stu10324    28d5860d    stu10327    11ea966b
    
    > paste -sd '=\n' test.txt #这是paste命令的特殊用法,轮流用=和\n做分隔符(\n是换行符,是不可见的)
    stu10309=7f753cc3
    stu10312=636e026d
    stu10315=18273b95
    stu10318=d6908f61
    stu10321=c441a16e
    stu10324=28d5860d
    stu10327=11ea966b
  2. 方法二:采用paste命令加-d参数实现。

    > paste -d '=' - - < test.txt #“-”这种用法在命令里很少见,功能是不从文本读取输入,而是从标准输入读入。每1个“-”代表读入的一行,所以这里有两个“- -”,并用“=”进行分隔。
    stu10309=7f753cc3
    stu10312=636e026d
    stu10315=18273b95
    stu10318=d6908f61
    stu10321=c441a16e
    stu10324=28d5860d
    stu10327=11ea966b
  3. 方法三:采用xargs+sed命令实现。

    > xargs -n 2 < test.txt #-n参数表示多少个字符串为一组
    stu10309 7f753cc3
    stu10312 636e026d
    stu10315 18273b95
    stu10318 d6908f61
    stu10321 c441a16e
    stu10324 28d5860d
    stu10327 11ea966b
    
    > xargs -n 2 <test.txt | sed 's# #=#g'  #将上述结果中的空格替换为=号。
    stu10309=7f753cc3
    stu10312=636e026d
    stu10315=18273b95
    stu10318=d6908f61
    stu10321=c441a16e
    stu10324=28d5860d
    stu10327=11ea966b
  4. 方法四:sed的特殊应用。

    > sed 'N;s#\n#=#g' test.txt
    stu10309=7f753cc3
    stu10312=636e026d
    stu10315=18273b95
    stu10318=d6908f61
    stu10321=c441a16e
    stu10324=28d5860d
    stu10327=11ea966b  

sed内置命令N的作用:不会清空模式空间内容,并且从输入文件中读取下一行数据,追加到模式空间中,两行数据以换行符n连接。
第一行是“stu10312”存入模式空间,碰到命令“N”,读取第二行“636e026d”,此时模式空间内容为“stu10312n636e026d”;然后执行“s#n#=#g”将“n”替换为“=”,即为“stu0312=636e026d”,输出到屏幕上,第一个循环结束;后面的循环和前面的思路一样,直到文件结束。

11. sort:文本排序

功能说明

sort命令将输入的文件内容按照指定的规则进行排序,然后将排序结果输出。

语法格式

sort [option] [file]
sort [选项] [文件]

选项说明

  • -b 忽略每行开头存在的空格字符
  • -n 依照数值的大小进行排序
  • -r 倒序排列
  • -u 去除重复行
  • -t 指定分隔符
  • -k 按指定区间排序

使用范例

  1. 默认以行为单位进行比较

    > cat test.txt
    10.0.0.4
    10.0.0.4
    10.0.0.4
    10.0.0.5
    10.0.0.4
    10.0.0.8
    
    > sort test.txt #不接收任何参数,会将文件内容转换成ASCII码,然后进行比较。因为在ASCII码中,数字的排序和我们的认知是一样的,因此结果如下所示。
    10.0.0.4
    10.0.0.4
    10.0.0.4
    10.0.0.4
    10.0.0.5
    10.0.0.8
    
    #默认比较的原则是从首字符向后,依次按ASCII码值进行比较,输出默认按升序进行排列。
  2. 通过参数-n使输出按数字从小到大的顺序来排列

    > sort -n test.txt  #使用-n选项直接按照数字从小到大的顺序来排序。
    10.0.0.4
    10.0.0.4
    10.0.0.4
    10.0.0.4
    10.0.0.5
    10.0.0.8
  3. 通过参数-r使输出按降序排列

    > sort -nr test.txt #-r选项表示反转的意思,sort命令默认按照升序(从小到大)进行排序,使用-r选项就变成降序了(从大到小)。
    10.0.0.8
    10.0.0.5
    10.0.0.4
    10.0.0.4
    10.0.0.4
    10.0.0.4
  4. 通过参数-u去除重复行

    > sort -u test.txt   #使用-u选项能够去除文件的重复行
    10.0.0.4
    10.0.0.5
    10.0.0.8
  5. 通过参数-t、-k指定列排序

    > cat test.txt
    10.0.0.4  r
    10.0.0.4  g
    10.0.0.4  a
    10.0.0.5  n
    10.0.0.4  q
    10.0.0.8  l
    
    > sort test.txt  #默认是按第1列进行排序。
    10.0.0.4  a
    10.0.0.4  g
    10.0.0.4  q
    10.0.0.4  r
    10.0.0.5  n
    10.0.0.8  l
    
    > sort -t " " -k2 test.txt #-t选项指定以空格为分隔符,-k选项后接2即表示按照第2列进行排序。
    10.0.0.4  a
    10.0.0.4  g
    10.0.0.8  l
    10.0.0.5  n
    10.0.0.4  q
    10.0.0.4  r
  6. 参数-t、-k的进阶使用

要求:先按IP地址的第3列排序,再按IP地址的第4列排序

> cat arp.txt
192.168.3.1 00:0F:AF:81:19:1F   #192.168.3(第三列).1(第四列)。
192.168.3.2 00:0F:AF:85:6C:25
192.168.3.3 00:0F:AF:85:70:42
192.168.2.20 00:0F:AF:85:55:DE
192.168.2.21 00:0F:AF:85:6C:09
192.168.2.22 00:0F:AF:85:5C:41
192.168.0.151 00:0F:AF:85:6C:F6
192.168.0.152 00:0F:AF:83:1F:65
192.168.0.153 00:0F:AF:85:70:03
192.168.1.10 00:30:15:A2:3B:B6
192.168.1.11 00:30:15:A3:23:B7
192.168.1.12 00:30:15:A2:3A:A1
192.168.1.1 00:0F:AF:81:19:1F
192.168.2.2 00:0F:AF:85:6C:25
192.168.3.3 00:0F:AF:85:70:42
192.168.2.20 00:0F:AF:85:55:DE
192.168.1.21 00:0F:AF:85:6C:09
192.168.2.22 00:0F:AF:85:5C:41
192.168.0.151 00:0F:AF:85:6C:F6
192.168.1.152 00:0F:AF:83:1F:65
192.168.0.153 00:0F:AF:85:70:03
192.168.3.10 00:30:15:A2:3B:B6
192.168.1.11 00:30:15:A3:23:B7
192.168.3.12 00:30:15:A2:3A:A1

#排序
> sort -n -t. -k3,3 -k4.1,4.3 arp.txt
192.168.0.151 00:0F:AF:85:6C:F6
192.168.0.151 00:0F:AF:85:6C:F6
192.168.0.152 00:0F:AF:83:1F:65
192.168.0.153 00:0F:AF:85:70:03
192.168.0.153 00:0F:AF:85:70:03
192.168.1.1 00:0F:AF:81:19:1F
192.168.1.10 00:30:15:A2:3B:B6
192.168.1.11 00:30:15:A3:23:B7
192.168.1.11 00:30:15:A3:23:B7
192.168.1.12 00:30:15:A2:3A:A1
192.168.1.21 00:0F:AF:85:6C:09
192.168.1.152 00:0F:AF:83:1F:65
192.168.2.2 00:0F:AF:85:6C:25
192.168.2.20 00:0F:AF:85:55:DE
192.168.2.20 00:0F:AF:85:55:DE
192.168.2.21 00:0F:AF:85:6C:09
192.168.2.22 00:0F:AF:85:5C:41
192.168.2.22 00:0F:AF:85:5C:41
192.168.3.1 00:0F:AF:81:19:1F
192.168.3.2 00:0F:AF:85:6C:25
192.168.3.3 00:0F:AF:85:70:42
192.168.3.3 00:0F:AF:85:70:42
192.168.3.10 00:30:15:A2:3B:B6
192.168.3.12 00:30:15:A2:3A:A1
  • -n:按数字排序。
  • -t.:按“.”作为分隔域。
  • -k3,3:按第3个字段开始到第3个字段结束排序。
  • -k4.1,4.3:按第4个字段第1个字符开始到第4个字段第3个字符结束排序。
  • “.”:点号连接的是字符。
  • “,”:逗号连接的是字段。

生产案例

以aa-cd-dd-xx中的最后一列xx进行分组,再对每组中的“IP:2.2.3.XXX”的最后一列XXX进行排序。

> cat sort.txt
ab-cd-rc-ab 3.2.3.46
ab-cd-cc-ee 1.2.3.41
ab-cd-cc-aa 1.2.3.42
ab-cd-cc-aa 1.2.3.42
fd-fe-er-fe 2.3.4.51
aa-er-vd-cd 3.4.5.61
zz-sd-jk-ee 5.6.7.82
ee-ad-df-fc 4.5.6.7
ee-ad-df-fc 4.5.6.21
ee-ad-df-fc 4.5.6.9
ad-ee-cd-er 5.4.3.23
bc-ki-ee-ee 0.3.4.5
bc-ki-ee-db 0.3.4.125
bc-ki-ee-db 0.3.4.12
bc-ki-de-fg 0.3.4.225
bc-ki-de-fg 0.3.4.25

#排序
> sort -t "." -k 1.10,1.11 -k 4,4n sort.txt   #先分组然后排序。
ab-cd-cc-aa 1.2.3.42
ab-cd-cc-aa 1.2.3.42
ab-cd-rc-ab 3.2.3.46
aa-er-vd-cd 3.4.5.61
bc-ki-ee-db 0.3.4.12
bc-ki-ee-db 0.3.4.125
bc-ki-ee-ee 0.3.4.5
ab-cd-cc-ee 1.2.3.41
zz-sd-jk-ee 5.6.7.82
ad-ee-cd-er 5.4.3.23
ee-ad-df-fc 4.5.6.7
ee-ad-df-fc 4.5.6.9
ee-ad-df-fc 4.5.6.21
fd-fe-er-fe 2.3.4.51
bc-ki-de-fg 0.3.4.25
bc-ki-de-fg 0.3.4.225  

12. join:按两个文件的相同字段合并

功能说明

join命令针对每一对具有相同内容的输入行,整合为一行输出到标准输出,默认情况下是把输入的第一个字段作为连接字段,字段之间用空格隔开。join命令可以处理具有相关性的文件。

语法格式

join [option] [file1] [file2]
join [选项] [文件1] [文件2]

选项说明

  • -a 文件号 输出文件中不匹配的行,文件号可选值1或2,分别代表文件1和文件2
  • -i 比较忽略时忽略大小写
  • -1 字段 以第1个文件指定字段为基础进行合并
  • -2 字段 以第2个文件指定字段为基础进行合并

使用范例

合并文本

> cat a.txt
韩海林 21岁
海林韩 23岁
韩林海 22岁
林海韩 24岁

> cat b.txt
韩林海 男
海林韩 男
韩海林 男
林海韩 男

> join a.txt b.txt #说明:使用join合并文件的要求是2个文件必须是用sort排序后的。
join: file 1 is not in sorted order
join: file 2 is not in sorted order
韩海林 21岁 男

> sort a.txt >a.txtn  #将排序后的文件内容重定向到新的文件中。
> sort b.txt >b.txtn
> join a.txtn b.txtn  #使用join合并已经排序的文件。
林海韩 24岁 男
海林韩 23岁 男
韩林海 22岁 男
韩海林 21岁 男

13. uniq:去除重复行

功能说明

uniq命令可以输出或忽略文件中的重复行。在工作中,我们常用的场景是使用sort命令对文件排序,然后使用uniq命令去重并计数。

语法格式

uniq [option] [file]
uniq [选项] [文件]

选项说明

  • -c 去除重复行,并计算每行出现的次数
  • -d 只显示重复的行
  • -u 只显示唯一的行

使用范例

  1. 去重基本用法

    > cat test.txt
    10.0.0.4
    10.0.0.4
    10.0.0.4
    
    > uniq oldboy.txt    #不接任何参数即去除重复行。
    10.0.0.4
    
    > uniq -c oldboy.txt #参数-c显示相应行出现的次数。
    3 10.0.0.4
  2. 结合sort去重

    > cat test.txt
    10.0.0.4
    10.0.0.4
    10.0.0.4
    10.0.0.5
    10.0.0.4
    10.0.0.8
    
    > uniq test.txt
    10.0.0.4
    10.0.0.5
    10.0.0.4
    10.0.0.8
    
    #说明:还有2行一样的。
    > sort -n test.txt | uniq -c
    4 10.0.0.4
    1 10.0.0.5
    1 10.0.0.8

上面的示例结果表明uniq只能对相邻的重复行进行去重操作,因此应先用sort处理文件再排列

生产案例

处理以下文件内容,将域名取出,并根据域名进行计数排序处理。

> cat test.log
http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html
http://post.etiantian.org/2.html

> awk -F "/" '{print $3}' test.log
www.etiantian.org
www.etiantian.org
post.etiantian.org
mp3.etiantian.org
www.etiantian.org
post.etiantian.org

> awk -F "/" '{print $3}' test.log | sort | uniq -c
1 mp3.etiantian.org
2 post.etiantian.org
3 www.etiantian.org

> awk -F "/" '{print $3}' test.log | sort | uniq -c | sort -rn #将上面的结果倒序排列。
3 www.etiantian.org
2 post.etiantian.org
1 mp3.etiantian.org

> cut -d '/' -f3 test.log | sort | uniq -c | sort -rn #不用awk,用cut命令。
3 www.etiantian.org
2 post.etiantian.org
1 mp3.etiantian.org

14. wc:统计文件的行数、单词数或字节数

功能说明

wc命令用于统计文件的行数、单词数或字节数

语法格式

wc [option] [file]
wc [选项] [文件]

选项说明

  • -c 统计字节数
  • -l 统计行数
  • -m 统计字符数
  • -w 统计单词数
  • -L 打印最长行的长度

使用范例

  1. 查看文件的字节数、字数、行数

    > wc /etc/inittab #不接受任何参数
    26 149 884 /etc/inittab
    
    > wc -c /etc/inittab #字节数
    884 /etc/inittab
    
    > wc -l /etc/inittab #行数
    26 /etc/inittab
    
    > wc -m /etc/inittab #字符数
    884 /etc/inittab
    
    > wc -w /etc/inittab #单词数
    149 /etc/inittab
    
    > wc -L /etc/inittab #最长行长度
    78 /etc/inittab
  2. 选项-L的使用(通过for循环打印下面这句话中字母数不大于6的单词)

    # I am a teacher welcome to my training class.
    > for word in I am a teacher welcome to my training class.;do [ 'echo $word | wc -L' -le 6 ] && echo $word;done
    I
    am
    a
    to
    my
    class.
    
    #上面是将一个Shell的for循环改写成一行命令。这里用到了-L参数计算单词的长度。
    for word in I am a teacher welcome to my training class.
      do
        [ 'echo $word|wc -L' -le 6 ] && \
        echo $word
    done
  3. 查看登录系统的用户数。

    > who #who命令能够查看有哪些用户登录系统
    root     pts/0        2016-08-30 16:53 (10.0.0.1)
    root     pts/1        2016-08-30 19:00 (10.0.0.1)
    
    > who | wc -l #有时我们需要监控有多少用户登录系统,因此可用wc命令计算一共有几个人。
    2  

15. iconv:转换文件的编码格式

功能说明

iconv命令用于转换文件的编码风格

语法格式

iconv [option] [-f from-encoding] [-t to-encoding] [inputfile]
iconv [选项] [原编码] [新编码] [输入文件]

选项说明

  • -f encodingA 从编码A转换
  • -t encodingB 转换成编码B
  • -l 显示系统支持的编码
  • -o 将输出输入到指定文件

使用范例

Linux系统是UTF-8的编码,而Win7系统是GB2312的编码,从英文字符的角度来说,两者没有区别,但是Windows编辑的中文字符到Linux系统中就会有乱码,需要先转码再处理。

> cat GB2312.txt
                 #此行是乱码。
Hello.

> iconv -f gb2312 -t utf-8 GB2312.txt   #使用-f参数指定文件原来的编码为gb2312,使用-t参数指定将要转换的编码为utf-8。
你好。
Hello.

16. dos2unix:将DOS文件格式转换成UNIX格式

功能说明

将DOS(Windows系统)格式文件转换成UNIX格式(DOS/MAC to UNIX text file format converter)。DOS下的文本文件是以“rn”作为换行标志的,而UNIX下的文本文件是以“n”作为换行标志的。所以在Linux中使用Windows的文本文件时,常常会出现错误。为了避免这种错误,Linux提供了两种文本格式相互转化的命令:dos2unix和unix2dos,dos2unix把Windows文件的“rn”转化成Linux文件的“n”,unix2dos把Linux文件的“n”转化成Windows文件的“rn”。

语法格式

dos2unix [file]
dos2unix [文件]

使用范例

处理由Windows系统创建的脚本文件。
若是在Windows中用文本文档创建一个Shell脚本,并在创建完成后将这个脚本上传到Linux系统中,那么就会碰到下面的问题:

> cat shell_win.sh     #查看上传的文件内容,没有发现异常。
for word in I am a teacher welcome to my training class.
    do
        [ 'echo $word|wc -L' -le 6 ] && \
        echo $word
done

> sh shell_win.sh      #<==但是执行这个脚本就会报错了,再三地研究脚本也没有发现哪里出错了!!
'shell_win.sh: line 2: syntax error near unexpected token 'do
'shell_win.sh: line 2: '  do

> cat -A shell_win.sh  #其实脚本没有写错,只是在一个不适合的场合下写了个脚本。使用前面学过的cat命令-A参数,查看文件的不可见字符,会发现很多行尾有^M(\r\n),但是Linux是以“\n”结尾的,因此执行这种脚本就会报错。
for word in I am a teacher welcome to my training class.^M$
    do^M$
        [ 'echo $word|wc -L' -le 6 ] && \^M$
        echo $word^M$
done^M$

> dos2unix shell_win.sh  #使用dos2unix转码一下,直接接文件就可以了,支持同时转换多个文件。
dos2unix: converting file shell_win.sh to UNIX format ...

> cat -A shell_win.sh  #现在就可以发现文件结尾就是$(\n)。
for word in I am a teacher welcome to my training class.$
    do$
        [ 'echo $word|wc -L' -le 6 ] && \$
        echo $word$
done$

> sh shell_win.sh  #Shell脚本可以正常执行。
I
am
a
to
my
class.
  

17. diff:比较两个文件的不同

功能说明

diff命令可以逐行比较纯文本文件的内容,并输出文件的差异。

语法格式

diff [option] [file1] [file2]
diff [选项] [文件1] [文件2]

选项说明

  • -y 以并列的方式显示文件的异同之处
  • -W 在使用-y参数时,显示指定宽度
  • -c 使用上下文的输出格式
  • -u 使用统一格式输出

使用范例

  1. 比较两个文本文件的例子

    > cat test1
    1
    2
    3
    4
    5
    6
    
    > cat test2
    4
    5
    6
    7
    8
    
    > diff test1 test2
    1,3d0   #删除文件1的第1行到第3行,删除文件2的第0行,即不删除。
    < 1
    < 2
    < 3
    6a4,5   #文件1的第6行增加下面2行文本,即文本2的第4行和第5行。
    > 7
    > 8
    
    #以下是命令结果说明,diff默认的显示格式有如下三种提示。
    #a-add
    #c-change
    #d-delete
    #例如:在1,3d0和6a4,5中,字母d/a前面的数字是文本1的行号,字母后面的是文本2的行号。其中以“<”打头的行属于文件1,以“>”打头的行属于文件2。
  2. 并排格式输出

    > diff -y test1 test2       #使用-y参数就可以并排输出。
    1    <
    2    <
    3    <
    4    4
    5    5
    6    6
        >    7
        >    8
    
    > diff  -y -W 30 test1 test2 #如果觉得上面太宽,则可以使用-W参数指定宽度。
    1            <
    2            <
    3            <
    4            4
    5            5
    6            6
                 >            7
                 >            8
                 
    # 命令结果说明具体如下。
    # “-”表示test2比test1少的行数。
    # “+”表示test2比test1多的行数。
  3. 上下文格式输出

    > diff -c test1 test2   #参数-c可以上下文输出。
    *** test1            2020-01-01 00:00:00.000000000 +0800
    --- test2            2020-01-01 00:00:00.000000000 +0800
    ***************
    *** 1,6 ****
    - 1
    - 2
    - 3
      4
      5
      6
    --- 1,5 ----
      4
      5
      6
    + 7
    + 8
  4. 统一格式输出

    > diff -u test1 test2  #参数-u统一格式输出。
    --- test1            2020-01-01 00:00:00.000000000 +0800
    +++ test2            2020-01-01 00:00:00.000000000 +0800
    @@ -1,6 +1,5 @@
    -1
    -2
    -3
     4
     5
     6
    +7
    +8
  5. 比较两个目录

    > diff /etc/rc3.d/ /etc/rc6.d/  #diff不仅可以比较文件内容的区别,还能比较目录下文件的区别。
    Only in /etc/rc6.d/: K25sshd
    Only in /etc/rc6.d/: K60crond
    Only in /etc/rc6.d/: K88rsyslog
    Only in /etc/rc6.d/: K90network
    Only in /etc/rc6.d/: S00killall
    Only in /etc/rc6.d/: S01reboot
    Only in /etc/rc3.d/: S10network
    Only in /etc/rc3.d/: S12rsyslog
    Only in /etc/rc3.d/: S55sshd
    Only in /etc/rc3.d/: S90crond
    Only in /etc/rc3.d/: S99local

18. vimdiff:可视化比较工具

功能说明

vimdiff调用vim打开文件,可以同时打开2个、3个或4个文件,最多4个文件,并且会以不同的颜色来区分文件的差异。

语法格式

vimdiff [option] [file1] [file2]
vimdiff [选项] [文件1] [文件2]

使用范例

比较两个文本文件的异同

> vimdiff test1 test2 #退出vimdiff界面需要连续执行2次退出vim的操作(:q),vim命令在后面将会有详细的讲解。因为vimdiff命令调用的是vim功能,所以退出操作和vim一致。

19. rev:反向输出文件内容

功能说明

rev命令可以按行反向输出文件内容

语法格式

rev [file]
rev [文件]

使用范例

字符串反转

> echo {1..10}
1 2 3 4 5 6 7 8 9 10

> echo {1..10} | rev  #上面的字符反着写了。
01 9 8 7 6 5 4 3 2 1

20. tr:替换或删除字符

功能说明

tr命令从标准输入中替换、缩减或删除字符,并将结果写到标准输出

语法格式

tr [option] [SET1] [SET2]
tr [选项] [字符1] [字符2]

选项说明

  • -d 删除字符
  • -s 保留连续字符的第一个字符,删除其他字符
  • -c 使用第一个字符串的补集,取反

使用范例

  1. 将文件中出现的”abc“替换成”xyz“

    > cat test.txt
    I am a superman.
    I like linux.
    My blog is https://www.leeyiding.com.
    My email is me@leeyiding.com.
    My QQ number is 1843272640.
    
    > tr 'abc' 'xyz' < test.txt #tr命令接受文件比较特殊,需要输入重定向符号“<”
    I xm x supermxn.
    I like linux.
    My ylog is https://www.leeyiding.zom.
    My emxil is me@leeyiding.zom.
    My QQ numyer is 1843272640.
    
    #凡是在文本中出现的“a”均应转换成“x”,“b”均应转换成“y”,“c”均应转换成“z”,而不是仅仅将字符串“abc”替换为字符串“xyz”
  2. 使用tr命令统一大小写

    > tr '[a-z]' '[A-Z]' < test.txt 
    I AM A SUPERMAN.
    I LIKE LINUX.
    MY BLOG IS HTTPS://WWW.LEEYIDING.COM.
    MY EMAIL IS ME@LEEYIDING.COM.
    MY QQ NUMBER IS 1843272640.
    
    #[a-z]是26个小写字母的缩写,[A-Z]是26个大写字母的缩写。因此本例是将a替换为A,b替换为B…z替换为Z。
    
    > tr '[A-Z]' '[a-z]' < test.txt #大写转小写
    i am a superman.
    i like linux.
    my blog is https://www.leeyiding.com.
    my email is me@leeyiding.com.
    my qq number is 1843272640.
  3. 将数字0-9替换为a-j

    > tr '[0-9]' '[a-j]' < test.txt #数字0替换为a,1替换为b,一一对应
    I am a superman.
    I like linux.
    My blog is https://www.leeyiding.com.
    My email is me@leeyiding.com.
    My QQ number is biedchcgea.
  4. 删除文件中出现的superman中的每个字符

    > tr -d 'superman' < test.txt 
    I   .
    I lik lix.
    My blog i htt://www.lyidig.co.
    My il i @lyidig.co.
    My QQ b i 1843272640.
    
    #凡是文件中出现的“s”、“u”、“p”、“e”、“r”、“m”、“a”、“n”字符都会删除,而不是只删除字符串“superman”
  5. 删除文件中出现的换行“n”、制表“t”字符

    > tr -d '\t\n' < test.txt 
    I am a superman.I like linux.My blog is https://www.leeyiding.com.My email is me@leeyiding.com.My QQ number is 1843272640.
    
    #使用-d参数删除所有的换行符和制表符,所有行都变成一行了,字母都连在一起了
  6. 删除连续字符

    > echo 'sssssuuuuuuuppeeerrrrrmaaaan' | tr -s superman
    superman
  7. 取反功能

    > tr '[0-9]' '*' < test.txt #将所有数字均替换为*
    I am a superman.
    I like linux.
    My blog is https://www.leeyiding.com.
    My email is me@leeyiding.com.
    My QQ number is **********.
    
    > tr -c '[0-9]' '*' < test.txt #使用参数-c,除了数字,其他的字符包括换行符都会替换为*
    *******************************************************************************************************************1843272640**

21. od:按不同进制显示文件

功能说明

od命令用于输出文件的八进制、十六进制或者其他格式编码的字节,通常用于显示或查看文件中不能直接显示在终端的字符。

语法格式

od [option] [file]
od [选项] [文件]

选项说明

  • -A 地址进制 按指定的进制显示地址信息,地址进制包括:

    • o 八进制(系统默认值)
    • d 十进制
    • x 十六进制
    • n 不打印位移值
  • -t 显示格式 指定显示的格式,主要参数有:

    • a 命名字符,忽略高阶位
    • c ASCII字符或反斜杠序列,如n
    • d 有符号的十进制数
    • f 浮点数
    • o 八进制(系统默认值)
    • u 无符号十进制数
    • x 十六进制数

使用范例

  1. 查看二进制命令文件的内容

    > cat /bin/ls
    #显示结果为乱码内容
    
    > od -Ax -tcx /bin/ls | more #使用od命令可以查看内容
    000000 177   E   L   F 002 001 001  \0  \0  \0  \0  \0  \0  \0  \0  \0
                  464c457f        00010102        00000000        00000000
    000010 002  \0   >  \0 001  \0  \0  \0   H   K   @  \0  \0  \0  \0  \0
                  003e0002        00000001        00404b48        00000000
    000020   @  \0  \0  \0  \0  \0  \0  \0 030 304 001  \0  \0  \0  \0  \0
                  00000040        00000000        0001c418        00000000
    000030  \0  \0  \0  \0   @  \0   8  \0  \t  \0   @  \0 036  \0 035  \0
                  00000000        00380040        00400009        001d001e
    000040 006  \0  \0  \0 005  \0  \0  \0   @  \0  \0  \0  \0  \0  \0  \0
                  00000006        00000005        00000040        00000000
    000050   @  \0   @  \0  \0  \0  \0  \0   @  \0   @  \0  \0  \0  \0  \0
                  00400040        00000000        00400040        00000000
    000060 370 001  \0  \0  \0  \0  \0  \0 370 001  \0  \0  \0  \0  \0  \0
                  000001f8        00000000        000001f8        00000000
    000070  \b  \0  \0  \0  \0  \0  \0  \0 003  \0  \0  \0 004  \0  \0  \0
                  00000008        00000000        00000003        00000004
    000080   8 002  \0  \0  \0  \0  \0  \0   8 002   @  \0  \0  \0  \0  \0
                  00000238        00000000        00400238        00000000
    000090   8 002   @  \0  \0  \0  \0  \0 034  \0  \0  \0  \0  \0  \0  \0
                  00400238        00000000        0000001c        00000000
    0000a0 034  \0  \0  \0  \0  \0  \0  \0 001  \0  \0  \0  \0  \0  \0  \0
                  0000001c        00000000        00000001        00000000
    0000b0 001  \0  \0  \0 005  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
                  00000001        00000005        00000000        00000000
    0000c0  \0  \0   @  \0  \0  \0  \0  \0  \0  \0   @  \0  \0  \0  \0  \0
                  00400000        00000000        00400000        00000000
    0000d0 374 223 001  \0  \0  \0  \0  \0 374 223 001  \0  \0  \0  \0  \0
                  000193fc        00000000        000193fc        00000000
    0000e0  \0  \0      \0  \0  \0  \0  \0 001  \0  \0  \0 006  \0  \0  \0
                  00200000        00000000        00000001        00000006
    .....................

22. tee:多重定向

功能说明

tee命令用于将数据重定向到文件,同时提供一份重定向数据的副本作为后续命令的标准输入。简单地说就是把数据重定向到给定文件和屏幕上。

语法格式

tee [option] [file]
tee [选项] [文件]

选项说明

  • -a 向文件追加内容,而不是覆盖

使用范例

  1. tee命令允许标准输出同时把内容写入(覆盖)到文件中。

    > ls #下面是当前目录的内容。
    anaconda-ks.cfg  GB2312.txt  install.log  install.log.syslog  test.txt
    
    > ls | tee ls.txt  #ls命令接管道和tee命令,在屏幕上输出ls的结果,同时将结果写入到ls.txt。
    anaconda-ks.cfg
    GB2312.txt
    install.log
    install.log.syslog
    test.txt
    
    > cat ls.txt #同时ls命令输出的内容又被写入到ls.txt文件中,会清空ls.txt的原有内容,类似重定向符号(>)。
    anaconda-ks.cfg
    GB2312.txt
    install.log
    install.log.syslog
    test.txt
  2. tee命令允许标准输出同时把内容追加到文件中。

    > ls | tee -a ls.txt #使用参数-a可以追加内容到文件中,不会清空文件中已有的内容。
    anaconda-ks.cfg
    GB2312.txt
    install.log
    install.log.syslog
    ls.txt
    test.txt
    
    > cat ls.txt
    anaconda-ks.cfg
    GB2312.txt
    install.log
    install.log.syslog
    test.txt                          #没有覆盖ls.txt文件以前的内容。
    anaconda-ks.cfg
    GB2312.txt
    install.log
    install.log.syslog
    ls.txt
    test.txt
    
    > ls | tee ls.txt    #不加参数-a,覆盖了ls.txt文件以前的内容。
    anaconda-ks.cfg
    GB2312.txt
    install.log
    install.log.syslog
    ls.txt
    test.txt
    
    > cat ls.txt
    anaconda-ks.cfg
    GB2312.txt
    install.log
    install.log.syslog
    ls.txt  
    test.txt

版权属于:LeeYD · Blog
本文标题:Linux笔记13-文件过滤及内容处理
本文链接:https://www.leeyiding.com/archives/37/
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 4.0 许可协议
若转载本文,请标明出处并告知本人

最后编辑于: 2020 年 01 月 27 日
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码