cat

示例:

1、查看文件的全部内容,打印在屏幕上

Linux文本处理工具_Linux三剑客

2、查看内容时显示一些隐藏的字符

Linux文本处理工具_字符编码_02

3、从键盘输入获取内容,以自定义字符串结束(例如:“EOF”),打印内容在屏幕上

Linux文本处理工具_文本处理_03

4、从键盘输入获取内容,以自定义字符串结束(例如:“EOF”),写入内容到文件中

Linux文本处理工具_文件比对_04

5、查看内容时显示行号

Linux文本处理工具_文件比对_05

使用nl命令也可以显示行号,区别在于nl命令不会为空行标记行号

Linux文本处理工具_正则表达式_06

more 与 less

more 与less 命令可以翻动查看文本内容

more 命令浏览文本时可用的指令:

  • 空格键(space)   向下翻一页
  • 回车键(Enter)   向下翻一行
  • /keywords    向下搜索这个关键字“keywords”
  • :f   显示文件名以及所在的行号
  • q   退出
  • b或“Ctrl + b”   往回翻一页,这个操作仅对文件有用

less 命令浏览文本时可用的指令:

  • 空格键(space) 向下翻一页
  • [PageDown] 向下翻一页
  • [PageUp] 向上翻一页
  • j 向上翻一行
  • k 向上翻一行
  • b或“Ctrl + b”   往回翻一页
  • g 跳转到第一行
  • G 跳转到最后一行
  • /keywords 向下搜索这个关键字“keywords”
  • ?keywords 向上搜索这个关键字“keywords”
  • n 重复前面一个搜索动作
  • N 反向重复前面一个搜索动作
  • v 调用vim编辑器编辑这个文件,这个操作仅对文件有用
  • q 退出

head 与 tail

head 与tail 命令可以查看文件部分内容,head查看头部,tail查看尾部,使用-n选项指定查看的行数,默认为10行,n可以省略(例如:查看前3行内容可以写成head -3),tail命令使用-f选项可以实时查看文件内容的变化,常用于查看日志文件

示例:

1、查看/etc/passwd文件前10行内容

Linux文本处理工具_文件比对_07

2、查看/etc/passwd文件前3行内容

Linux文本处理工具_Linux三剑客_08

3、查看/etc/passwd文件最后10行内容

Linux文本处理工具_Linux三剑客_09

4、查看/etc/passwd文件最后3行内容

Linux文本处理工具_字符编码_10

5、查看/etc/passwd文件第15-20行内容

Linux文本处理工具_文件比对_11

可以配合使用cat -n验证一下

Linux文本处理工具_文件比对_12

6、实时查看/var/log/message日志内容

[root@10-60-102-196 ~]# tail -f /var/log/messages

Linux文本处理工具_字符编码_13

这里有个小技巧:我们可以在最后一行,也就是光标闪烁的位置划上一条线,区分日志旧的内容和新增的内容,这条线并不会写入到文件中,仅仅是为了在视觉上更好作区分

例如:新开一个窗口,安装httpd 软件包,再回到这个窗口查看日志新增了哪些内容

[root@10-60-102-196 ~]# yum -y install httpd

Linux文本处理工具_正则表达式_14

大部分是刷新man_db 有关的内容

基本正则表达式

基本正则表达式(Basic Regular Expression,BRE),又称为标准正则表达式,是最早制订的正则表达式规范,仅支持最基本的元字符集。基本正则表达式是POSIX规范制订的两种正则表达式语法标准之一,另外一种语法标准称为扩展正则表达式,将在随后介绍。正则表达式需要配合支持正则表达式的程序使用,例如grep,用来查找出匹配表达式规则的内容,下面是一些常用的基本正则表达式字符

字符

含义

^

在每行的开始进行匹配

$

在每行的末尾进行匹配

\<

在字(word,由字母/下划线/数字组成)的开始进行匹配

\>

在字(word,由字母/下划线/数字组成)的末尾进行匹配

.

对任何单个字符进行匹配

[str]

对str 中的任何单个字符进行匹配

[^str]

对任何不在str 中的单个字符进行匹配

[a-b]

对a 到b 之间的任何字符进行匹配

\

抑制后面的一个字符的特殊含义

*

对前一项(item)进行0 次或多次重复匹配

扩展正则表达式

扩展正则表达式(Extended Regular Expression,ERE)支持比基本正则表达式更多的元字符,但是扩展正则表达式对有些基本正则表达式所支持的元字符并不支持。前面介绍的元字符^$.*[][^]这6 个元字符在扩展正则表达式都得到了支持,并且其意义和用法都完全相同,不再重复介绍。接下来重点介绍一下在扩展正则表达式中新增加的一些元字符。同样地,扩展正则表达式需要配合支持扩展正则表达式的程序使用,egrep支持扩展正则表达式,相当于grep -E,下面是一些常用的扩展正则表达式字符

字符

含义

+

对前一项进行1 次或多次重复匹配

?

对前一项进行0 次或1 次重复匹配

{j}

对前一项进行j 次重复匹配

{j,}

对前一项进行j 次或更多次重复匹配

{,k}

对前一项最多进行k 次重复匹配

{j,k}

对前一项进行j 到k 次重复匹配

s|t

匹配s 项或t 项中的一项

(exp)

将exp作为单项处理

linux三剑客

grep

grep 命令可使用关键字检索文本内容中匹配的行,以下是一些常用选项:

-i:忽略大小写

-n:打印匹配的行号

-o:只显示匹配的内容

-c:如果匹配成功,则将匹配到的行数打印出来

-v:反向匹配

-q:静默模式,没有任何输出,得用$?来判断执行成功没有,即有没有过滤到想要的内容

-AX:将匹配行及其后面的X行一并打印出来

-BX:将匹配行及前面的X行一并打印出来

-CX:将匹配行及前后X行一并打印出来

-r:递归搜索目录,根据关键字搜索文件

-l:如果匹配成功,只将文件名打印出来,失败则不打印,通常-rl配合使用

--color=auto:用color 颜色高亮显示匹配到的关键字

示例:

1、用关键字root 检索/etc/ssh/sshd_conf 文件的内容

Linux文本处理工具_正则表达式_15

2、用关键字root 检索/etc/ssh/sshd_conf 文件的内容,忽略大小写

Linux文本处理工具_文本处理_16

3、用关键字root 检索/etc/ssh/sshd_conf 文件的内容,忽略大小写,并打印匹配的行号

Linux文本处理工具_文本处理_17

4、用关键字root 检索/etc/ssh/sshd_conf 文件的内容,忽略大小写,只显示匹配的内容

Linux文本处理工具_文本处理_18

5、用关键字root 检索/etc/ssh/sshd_conf 文件的内容,忽略大小写,如果匹配成功,将匹配到的行数打印出来

Linux文本处理工具_正则表达式_19

6、用关键字#检索/root/.bashrc 文件的内容,反向匹配,将不含有# 号的行打印出来

Linux文本处理工具_Linux三剑客_20

7、用关键字alias 检索/root/.bashrc 文件的内容,使用-q静默模式

Linux文本处理工具_文件比对_21

使用echo $?命令查看上一条命令的返回值,判断有没有过滤到想要的内容,如果返回值为0,则过滤到了想要的内容,如果不为0,则没有过滤到

Linux文本处理工具_文件比对_22

7、用关键字hello 检索/root/.bashrc 文件的内容,使用-q静默模式,判断有没有过滤到想要的内容

Linux文本处理工具_Linux三剑客_23

没有过滤到hello

8、用关键字root 检索/etc/ssh/sshd_conf 文件的内容,打印行号,将匹配行及其后面的5行一并打印出来

Linux文本处理工具_正则表达式_24

9、用关键字root 检索/etc/ssh/sshd_conf 文件的内容,打印行号,将匹配行及其前面的5行一并打印出来

Linux文本处理工具_字符编码_25

10、用关键字root 检索/etc/ssh/sshd_conf 文件的内容,打印行号,将匹配行及其前后的5行一并打印出来

Linux文本处理工具_Linux三剑客_26

11、递归搜索/root 目录,根据关键字alias 搜索文件

Linux文本处理工具_文本处理_27

12、递归搜索/root 目录,根据关键字alias 搜索文件,只将文件名打印出来

Linux文本处理工具_Linux三剑客_28

13、用关键字man_db 检索/etc/man_db.conf 文件的内容,用color 颜色高亮显示匹配到的关键字

默认情况下,grep 命令有一个别名,自带了--color=auto选项,所以检索出来的关键字会高亮显示,即使没有手动指定该选项

Linux文本处理工具_Linux三剑客_29

Linux文本处理工具_文本处理_30

执行grep 命令时,使用程序的绝对路径,可以避免别名的效果

Linux文本处理工具_文本处理_31

grep 命令支持基本正则表达式,如果要使用扩展正则,可用egrep,或grep -E命令

示例:

1、检索/etc/man_db.conf 文件中以MANDB 开头的行

Linux文本处理工具_正则表达式_32

如果不带^号,则不以MANDB 开头的行也会被检索出来

Linux文本处理工具_文件比对_33

2、检索/etc/man_db.conf 文件中以关键字man 结尾的行

Linux文本处理工具_Linux三剑客_34

3、在字(word)的开始进行匹配

为方便测试,我们准备一个文本文件example.txt,内容如下:

Linux文本处理工具_文件比对_35

示例:

1、检索example.txt 文件的内容,在字的开始匹配关键字root

Linux文本处理工具_文本处理_36

注意观察红色高亮部分,root_root 中间由下划线_连接,是一个字(word),所以只匹配前一个root,root:root 和root/root中间不是下划线连接,所以前后root 是两个字(word),两个字都匹配

2、检索example.txt 文件的内容,在字的末尾匹配关键字root

Linux文本处理工具_文本处理_37

3、检索example.txt 文件的内容,关键字以r开头,以t结尾,中间用.表示单个字符

Linux文本处理工具_Linux三剑客_38

4、检索example.txt 文件的内容,对ltr中的任何单个字符进行匹配

Linux文本处理工具_Linux三剑客_39

5、检索example.txt 文件的内容,对不在ltr中的任何单个字符进行匹配

Linux文本处理工具_文件比对_40

6、检索example.txt 文件的内容,对az之间的任何字符进行匹配

Linux文本处理工具_字符编码_41

7、检索example.txt 文件的内容,对19之间的任何字符进行匹配

Linux文本处理工具_Linux三剑客_42

8、检索/etc/profile 文件的内容,匹配关键字$PATH

Linux文本处理工具_文本处理_43

$符号在bash shell 中有特殊含义,需要用\对其转义

9、检索example.txt 文件的内容,对以t开头的关键字进行匹配,中间用.*表示任意长度的字符,或没有字符

Linux文本处理工具_字符编码_44

为方便测试,编辑example.txt 文件添加一些内容

Linux文本处理工具_字符编码_45

11、检索example.txt 文件的内容,对以ro开头的关键字进行匹配,o可以出现一次或多次

Linux文本处理工具_文件比对_46

12、检索example.txt 文件的内容,对关键字ro进行匹配,o可以没有或出现1次

Linux文本处理工具_正则表达式_47

13、检索example.txt 文件的内容,对关键字r进行匹配,r至少出现2 次,或更多次

Linux文本处理工具_文本处理_48

14、检索example.txt 文件的内容,对关键字ro进行匹配,o最多出现3次,或可以没有

Linux文本处理工具_正则表达式_49

15、检索example.txt 文件的内容,对关键字r进行匹配,r至少出现2 次,最多出现4 次

Linux文本处理工具_正则表达式_50

16、检索example.txt 文件的内容,对关键字rort进行匹配

Linux文本处理工具_文本处理_51

17、检索example.txt 文件的内容,对关键字root进行匹配,root至少出现2 次

Linux文本处理工具_文件比对_52

awk

简介

awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

awk 是一种很棒的语言,它适合文本处理和报表生成,其语法较为常见,借鉴了某些语言的一些精华,如 C 语言等。在 linux 系统日常处理工作中,发挥很重要的作用,掌握了 awk将会使你的工作变的高大上。 awk 是三剑客的老大,利剑出鞘,必会不同凡响。

使用方法
awk '{pattern + action}' {filenames}

尽管操作可能会很复杂,但语法总是这样,其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号{}不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。在 awk 中,花括号用于将几块代码组合到一起,这一点类似于 C 语言。

awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。

通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

awk 对输入文件中的每一行都执行下图这个脚本,这是一个示例,引用/etc/passwd 文件说明,$0表示一行,$1表示第一个字段,$2表示第二个字段,以此类推...   FS表示字段分隔符,默认为一个或多个空格,NF表示第几个字段,NR表示第几行,RS为分隔符,这只是其中最常用的几个内置变量,更多的内置变量在下文进行介绍。

Linux文本处理工具_文本处理_53

基本用法示例

准备测试文件,就以/etc/passwd 文件为例,拷贝一份到家目录下

Linux文本处理工具_文本处理_54

1、以:号为分隔符,打印每行第1 个字段

Linux文本处理工具_文本处理_55

2、以:号为分隔符,打印每行第1 个字段和第3 个字段

Linux文本处理工具_Linux三剑客_56

3、以:号为分隔符,打印每行第1 个字段和第3 个字段,中间用空格分开

Linux文本处理工具_正则表达式_57

4、以:号为分隔符,格式化输出内容,print 后面做字符串拼接

Linux文本处理工具_Linux三剑客_58

\t 表示为tab 键分隔符

5、查看passwd 文件第10 - 15 行内容

Linux文本处理工具_Linux三剑客_59

可以加上行号验证一下

Linux文本处理工具_Linux三剑客_60

6、准备一个测试文件,内容如下图

Linux文本处理工具_Linux三剑客_61

从该文件中过滤出‘Poe’字符串与233445566,最后输出结果为:Poe 233445566

Linux文本处理工具_字符编码_62

BEGIN 和END 模块

通常,对于每个输入行, awk 都会执行每个脚本代码块一次。然而,在许多编程情况中,可能需要在 awk 开始处理输入文件中的文本之前执行初始化代码。对于这种情况, awk 允许您定义一个 BEGIN 块。

因为 awk 在开始处理输入文件之前会执行 BEGIN 块,因此它是初始化 FS(字段分隔符)变量、打印页眉或初始化其它在程序中以后会引用的全局变量的极佳位置。
awk 还提供了另一个特殊块,叫作 END 块。 awk 在处理了输入文件中的所有行之后执行这个块。通常, END 块用于执行最终计算或打印应该出现在输出流结尾的摘要信息。

1、统计/etc/passwd 的账户人数

Linux文本处理工具_正则表达式_63

count 是自定义变量。之前的action{} 里都是只有一个print,其实print 只是一个语句,而action{} 可以有多个语句,以;号隔开。这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0

Linux文本处理工具_字符编码_64

2、统计某个文件夹下的文件总大小

Linux文本处理工具_字符编码_65

如果以M 为单位显示

Linux文本处理工具_文本处理_66

awk 运算符

Linux文本处理工具_文本处理_67

1、awk 赋值运算符:a+5; 等价于:a=a+5; 其他同理

Linux文本处理工具_Linux三剑客_68

%=是取余,^=**=都是求幂

2、awk 逻辑运算符

Linux文本处理工具_Linux三剑客_69

0为假,1为真

awk 正则运算符

Linux文本处理工具_文件比对_70

Linux文本处理工具_正则表达式_71

Linux文本处理工具_字符编码_72

Linux文本处理工具_文件比对_73

awk 关系运算符

如:> < 可以作为字符串比较,也可以用作数值比较,关键看操作数,如果是字符串就会转换为字符串比较。两个都为数字,才能转换为数值比较。字符串比较:按照ASCII 码的顺序比较。

Linux文本处理工具_字符编码_74

awk 算术运算符

所有用作算术运算符进行操作,操作数自动转为数值,所有非数值都变为0。

Linux文本处理工具_文件比对_75

这里的a++, ++a 与C 语言一样:a++是先赋值加1;++a是先加1 再赋值

三目运算符 ?:

Linux文本处理工具_Linux三剑客_76

awk 常用内置变量

Linux文本处理工具_文件比对_77

1、FS="\t" 一个或多个Tab 分隔

Linux文本处理工具_字符编码_78

查看隐藏字符,^I表示为Tab 分隔符,^II即为两个Tab 分隔符

Linux文本处理工具_字符编码_79

2、FS="[[:space:]+]" 一个或多个空格,默认的

Linux文本处理工具_正则表达式_80

Linux文本处理工具_文件比对_81

3、FS=[" ":]+   以一个或多个空格:分隔

Linux文本处理工具_文本处理_82

4、字段数量NF

Linux文本处理工具_Linux三剑客_83

5、记录数量NR

Linux文本处理工具_文件比对_84

6、RS 记录分隔符变量
将 FS 设置成"\n"告诉 awk 每个字段都占据一行。通过将 RS 设置成"",还会告诉 awk每个地址记录都由空行分隔。

Linux文本处理工具_文件比对_85

7、OFS 输出字段分隔符

Linux文本处理工具_文本处理_86

8、ORS 输出记录分隔符

Linux文本处理工具_文件比对_87

awk 正则

Linux文本处理工具_Linux三剑客_88

1、awk '/REG/{action}' file/REG/为正则表达式,可以将$0 中,满足条件的记录送入到:action 进行处理

Linux文本处理工具_字符编码_89

2、布尔表达式

awk '布尔表达式{action}' file 仅当对前面的布尔表达式求值为真时,awk 才执行代码块。

Linux文本处理工具_文件比对_90

awk 的 if、循环和数组
if 条件语句

1、awk 提供了非常好的类似于 C 语言的 if 语句。

Linux文本处理工具_字符编码_91

2、使用if 语句还可以将代码:

!/matchme/ {print $1,$3,$4}

转换成:

{
	if($0 !~/matchme/){
  	print $1,$3,$4
  }
}

Linux文本处理工具_正则表达式_92

while 循环结构

Linux文本处理工具_文件比对_93

do while 循环结构

do...while"循环永远都至少执行一次,它在代码块结尾处对条件求值,而不像标准 while 循环那样在开始处求值。

Linux文本处理工具_文本处理_94

for 循环

同C 语言的for 循环语法一样

Linux文本处理工具_正则表达式_95


break 和 continue

此外,如同 C 语言一样, awk 提供了 break 和 continue 语句。使用这些语句可以更好地控制 awk 的循环结构。

break 语句用于“逃出”最深层的循环。 "break"使循环立即终止,并继续执行循环代码块后面的语句。

Linux文本处理工具_字符编码_96

continue 语句用于打断本次循环,直接开始下一次循环

Linux文本处理工具_文件比对_97

数组

Linux文本处理工具_文本处理_98

1、数组的典型应用,查看服务器连接状态并汇总:

Linux文本处理工具_字符编码_99

常用字符串函数

Linux文本处理工具_文本处理_100

字符串函数的应用:

1、替换

Linux文本处理工具_文本处理_101

在info 中查找满足正则表达式,/[0-9]+/ 表示一位或多位数字,用!替换,并且替换后的值,赋值给info

给info值,默认是$0

2、查找

Linux文本处理工具_文本处理_102

3、匹配查找

Linux文本处理工具_文本处理_103

4、截取

Linux文本处理工具_正则表达式_104

从第4 个字符开始,截取10 个长度的字符

5、分割

Linux文本处理工具_文本处理_105

分割info 字符串,动态创建数组tA,以空格分隔

sed

简介

sed 全名为 stream editor,流编辑器,用程序的方式来编辑文本,功能相当的强大。是贝尔实验室的 Lee E.McMahon 在 1973 年到 1974 年之间开发完成,目前可以在大多数操作系统中使用,sed 的出现作为 grep 的继任者。与vim等编辑器不同,sed 是一种非交互式编辑器(即用户不必参与编辑过程),它使用预先设定好的编辑指令对输入的文本进行编辑,完成之后再输出编辑结构。sed 基本上就是在玩正则模式匹配,所以,玩sed的人,正则表达式一般都比较强。

工作原理

sed会一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,成为"模式空间",接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

sed 语法及常用选项

sed [选项] ‘command’ 文件名称

选项部分,常用选项包括-n,-e,-i,-f,-r 选项。

command部分包括:[地址1,地址2] [函数] [参数(标记)]

-n:sed默认会把模式空间处理完毕后的内容输出到标准输出,也就是输出到屏幕上,加上-n选项后被设定为静默模式,也就是不会输出默认打印信息,除非子命令中特别指定打印选项,则只会把匹配修改的行进行打印。

-e:如果需要用sed对文本内容进行多种操作,则需要执行多条子命令来进行操作。

-i:sed默认会把输入行读取到模式空间,简单理解就是一个内存缓冲区,sed子命令处理的内容是模式空间中的内容,而非直接处理文件内容。因此在sed修改模式空间内容之后,并非直接写入修改输入文件,而是打印输出到标准输出。如果需要修改输入文件,那么就可以指定-i选项。

-f:还记得 -e 选项可以来执行多个子命令操作吗,用分号分隔多个命令操作也是可以的,如果命令操作比较多的时候就会比较麻烦,这时候把多个子命令操作写入脚本文件,然后使用 -f 选项来指定该脚本。

-r:sed命令的匹配模式支持正则表达式的,默认只能支持基本正则表达式,如果需要支持扩展正则表达式,那么需要添加-r选项。

示例:

1、echo 一段内容,使用-e选项开启反斜杠转义功能,由管道符交由sed 处理,进行字符串替换

Linux文本处理工具_正则表达式_106

2、静默模式

Linux文本处理工具_Linux三剑客_107

sed 加了-n 选项后,什么也没有显示

3、静默模式,配合子命令p,只会把修改的行打印出来

Linux文本处理工具_字符编码_108

4、如果需要用sed 对文本内容进行多段函数的操作,使用 -e指定,或者两段函数之间使用;号隔开。

Linux文本处理工具_文本处理_109

Linux文本处理工具_正则表达式_110

5、sed 默认会把输入行读取到模式空间,简单理解就是一个内存缓冲区,sed 子命令处理的内容是模式空间中的内容,而非直接处理文件内容。因此在sed 修改模式空间内容之后,并非直接写入修改输入文件,而是打印输出到标准输出。如果需要修改输入文件,那么就可以指定-i选项。

Linux文本处理工具_文件比对_111

6、使用i.bak选项把修改内容保存到file.txt,同时会以file.txt.bak文件备份原来未修改文件内容,以确保原始文件内容安全性,防止错误操作而无法恢复原来内容。

Linux文本处理工具_正则表达式_112

7、将函数写入文件,一段函数一行,不需要用单引号,然后使用-f指定文件

Linux文本处理工具_文本处理_113

8、使用-r选项扩展正则

Linux文本处理工具_正则表达式_114

数字定址和正则定址

关于定址的概念:

默认情况下sed会对每一行内容进行匹配、处理、输出,某些情况不需要对处理的文本全部编辑,只需要其中的一部分,比如1-10行,偶数行,或者是包含"hello"字符串的行,这种情况下就需要我们去定位特定的行来处理,而不是全部内容,这里把这个定位指定的行叫做"定址"。

数字定址

数字定址其实就是通过数字去指定具体要操作编辑的行,数字定址有几种方式,每种方式都有不同的应用场景,下边以举例的方式来描述每种数字定址的用法。

示例:

1、将第4行中的第一个hello 字符串替换为A,其它行如果有hello也不会被替换。

Linux文本处理工具_Linux三剑客_115

2、将第2-4行中的第一个hello 字符串替换为A,其它行如果有hello也不会被替换。

Linux文本处理工具_文件比对_116

3、从第2行开始,再接着往下数4行,也就是2-6行,这些行会把hello字符替换为A。

Linux文本处理工具_字符编码_117

4、第4 行开始,到第6 行。解释6的由来:"4,~3"表示从4行开始到下一个3 的倍数,这里从4 开始算,那就是6 了,当然9 就不是了,因为是要求3 的第一个超过前边数字4的倍数,感觉这种适用场景不会太多。

Linux文本处理工具_正则表达式_118

5、从第4 行开始,每隔3 行就把hello 替换为A。比如从4 行开始,7 行,10 行等依次+3 行。这个比较常用,可以实现奇数和偶数行的操作。

Linux文本处理工具_正则表达式_119

6、$符号表示最后一行,和正则中的$ 符号类似,但是第1 行不用^ 表示,直接1 就行了。

Linux文本处理工具_正则表达式_120

7、!符号表示取反,该命令是将除了第1 行,其它行hello 替换为A,上述定址方式也可以使用!符号。

Linux文本处理工具_文本处理_121

正则定址

正则定址使用目的和数字定址完全一样,使用方式上有所不同,是通过正则表达式的匹配来确定需要处理编辑哪些行,其它行就不需要额外处理。

示例:

1、将匹配到nihao 的行执行删除操作。

Linux文本处理工具_文本处理_122

2、删除空行

Linux文本处理工具_正则表达式_123

3、匹配以TS 开头的行到TE 开头的行之间的行,把匹配到的这些行删除。

Linux文本处理工具_文件比对_124

4、其实数字定址和正则定址可以配合使用,匹配从第1行到TS开头的行,把匹配的行删除。

Linux文本处理工具_Linux三剑客_125

5、定址的分组命令

Linux文本处理工具_正则表达式_126

Linux文本处理工具_Linux三剑客_127

基本子命令

a 子命令a表示在指定行下边插入指定行的内容。

i 子命令i 和a 使用上基本上一样,只不过是在指定行上边插入指定行的内容。

c 子命令c 是表示把指定的行内容替换为自己需要的行内容。

d 子命令d 表示删除指定的行内容,比较简单,更容易理解。

y 子命令y 表示字符替换,可以替换多个字符,只能替换字符不能替换字符串,且不支持正则表达式。

= 子命令=,可以将行号打印出来。

r 子命令r,类似于a,也是将内容追加到指定行的后边,只不过r 是将指定文件内容读取并追加到指定行下边。 

s 子命令s 为替换子命令,是平时sed 使用的最多的子命令,没有之一。因为支持正则表达式,功能变得强大无比。

示例:

1、将message 文件中每一行下边都插入添加一行内容是A

Linux文本处理工具_Linux三剑客_128

2、将message 文件中1-2 行的下边插入添加一行内容是A

Linux文本处理工具_字符编码_129

3、将message 文件中1-2 行的下边分别添加3 行,3 行内容分别是A、B、C,这里使用了\n,插入多行内容都可以按照这种方式来实现

Linux文本处理工具_文件比对_130

4、将message 文件中每一行上边都插入添加一行内容是A

Linux文本处理工具_Linux三剑客_131

5、将message 文件中1-2 行的上边插入添加一行内容是A

Linux文本处理工具_字符编码_132

6、将message 文件中1-2 行的上边分别添加3 行,3 行内容分别是A、B、C,这里使用了\n,插入多行内容都可以按照这种方式来实现

Linux文本处理工具_Linux三剑客_133

7、将message 文件中所有行的内容都分别替换为A

Linux文本处理工具_文本处理_134

8、将message 文件中1-2 行的内容替换为A,注意这里说的是将1-2 行所有的内容只替换为一个A 内容,也就是1-2行内容编程了一行,定址如果连续就是这种情况。

Linux文本处理工具_正则表达式_135

9、将message 中1-2 行内容分别替换为了A,需要在替换内容上手动加换行\n,这样当然也可以将一行内容替换为多行内容。

Linux文本处理工具_正则表达式_136

10、将message 所有行全部删除,因为没有加定址表达式,所以平时如果需要删除指定行内容,需要在子命令前加定址表达式。

Linux文本处理工具_正则表达式_137

11、将message 文件中1-2 行的内容删除。

Linux文本处理工具_文本处理_138

12、把message 中所有a 字符替换为A 符号,所有b 字符替换为B 符号

Linux文本处理工具_正则表达式_139

强调一下,这里的替换源字符个数和目的字符个数必须相等;字符不支持正则表达式;源字符和目标字符每个字符需要一一对应。

13、将指定行的上边显示行号。

Linux文本处理工具_Linux三剑客_140

14、将a.txt 文件的内容读取并插入到message 文件第2 行的下边。

Linux文本处理工具_文件比对_141

下面着重说明一下子命令s

子命令s为替换子命令,是平时sed使用的最多的子命令,没有之一。因为支持正则表达式,功能变得强大无比,下边来详细地说说子命令s的使用方法。

基本语法:

[address] s/pattern/replacement/flags

s 字符串替换,替换的时候可以把/换成其它的符号,比如=,replacement 部分用下列字符会有特殊含义:

>>>  &:用正则表达式匹配的内容进行替换
>>>  \n:回调参数
>>>  \(\):保存被匹配的字符以备反向引用\n时使用,最多9个标签,标签书序从左到右

Flags

>>>  n:可以是1-512,表示第n次出现的情况进行替换
>>>  g:全局更改
>>>  p:打印模式空间的内容
>>>  w file:写入到一个文件file中

示例:

1、将message 每行包含的第一个hello 的字符串替换为HELLO,这是最基本的用法

Linux文本处理工具_文本处理_142

2、使用了扩展正则表达式,需要加-r选项

Linux文本处理工具_Linux三剑客_143

3、匹配正则,输出指定字段。再看下一个例子就明白了。

Linux文本处理工具_文本处理_144

4、\1表示正则第一个分组结果,\2表示正则匹配第二个分组结果,\3表示正则匹配第三个分组结果。

Linux文本处理工具_文本处理_145

5、&表示正则表达式匹配的整个结果集。

Linux文本处理工具_正则表达式_146

6、在匹配结果前后分别加了111、222

Linux文本处理工具_文件比对_147

7、在message 文件中每行的首尾分别加上111、222

Linux文本处理工具_Linux三剑客_148

8、把message 文件中每行的所有i字符替换为A,默认不加g标记时只替换每行的第一个字符。

Linux文本处理工具_正则表达式_149

9、把message 文件中每行的第2 个i 字符替换为A

Linux文本处理工具_正则表达式_150

10、加-p标记会把被替换的行打印出来,再加上-n选项会关闭模式空间打印模式,因此该命令的效果就是只显示被替换修改的行。

Linux文本处理工具_Linux三剑客_151

11、把message 文件中内容的每行第一个字符i 替换为A,然后把修改内容另存为b.txt 文件。

Linux文本处理工具_文本处理_152

12、把message 文件中每一行的第一个iI字符替换为A字符,也即是忽略大小写。

Linux文本处理工具_文本处理_153

模式空间与保持空间

模式空间初始化为空,处理完一行后会自动输出到屏幕并清除模式空间;保持空间初始化为一个空行,也就是默认带一个\n,处理完后不会自动清除。模式空间和保持空间,从程序的角度去看,其实就是sed 在工作的时候占用了一些内存空间和地址,sed工作完毕就会把内存释放并归还给操作系统。

大概简单描述一下sed 的工作流程,读取文件的一行,存入模式空间,然后进行所有子命令的处理,处理完后默认会将模式空间的内容输出打印到标准输出,也就是在屏幕上显示出来,接着清空模式空间的内存,继续读取下一行的内容到模式空间,继续处理,依次循环处理。

模式空间与保持空间的置换:

d  Delete pattern space.  Start next cycle.    删除pattern space(模式空间)的内容,开始下一个循环.

hH Copy/append pattern space to hold space.   复制/追加pattern space(模式空间)的内容到hold sp                    ace(保持空间).

gG Copy/append hold space to pattern space.   复制/追加hold space(保持空间)的内容到pattern sp                    ace(模式空间).

x Exchange the contents of the hold and pattern spaces.    交换hold space(保持空间)和pattern space           (模式空间)的内容.

准备测试文件内容:

Linux文本处理工具_文件比对_154

示例:

1、倒序输出文件内容,相当于tac命令的功能,处理第1 行时,不会把保持空间的内容追加到模式空间,把模式空间的内容覆盖到保持空间(1111),模式空间中的内容删除,然后处理第2 行,把保持空间的内容(1111)追加到模式空间,把模式空间的内容覆盖到保持空间(2222\n1111),模式空间中的内容删除,处理第3行... 以此类推,最后将处理完的内容输出,就是倒序的效果

Linux文本处理工具_文件比对_155

或者下面这样写也可以做到

Linux文本处理工具_文件比对_156

2、给文件内容的每一行下面插入一个空行

Linux文本处理工具_文件比对_157

3、将第1 行内容覆盖到保持空间,第2-3 行内容追加到保持空间,处理最后一行时把保持空间的内容追加到模式空间

Linux文本处理工具_Linux三剑客_158

4、将第1 行内容覆盖到保持空间,模式空间处理第2 行内容时与保持空间内容交换,处理第3 行内容时把保持空间的内容覆盖到模式空间,处理最后一行内容时把保持空间的内容追加到模式空间,最后将模式空间的内容输出

Linux文本处理工具_正则表达式_159

高级子命令

高级子命令比较少,但是比较复杂,平时用的也会相对少些,却也很重要,有的内容处理不用高级子命令是完成不了的。

n 读取下一行,遇到n 时会自动跳入下一行,例:'4{n;d}' 删除第5行。

N 多行操作命令,N 命令会将下一行文本内容添加到缓冲区已有数据之后(之间用换行符\n分隔),从而使前后两个文本行同时位于缓冲区中,sed 命令会将这两行数据当成一行来处理。 

D 多行删除命令,sed 不仅提供了单行删除命令d,也提供了多行删除命令D,其作用是只删除缓冲区中的第一行,也就是说,D 命令将缓冲区中第一个换行符(包括换行符)之前的内容删除掉。如果模式空间包含换行符,则删除直到第一个换行符的模式空间中的文本, 并不会读取新的输入行,而使用合成的模式空间重新启动循环。如果模式空间不包含换行符,则会像发出d命令那样启动正常的新循环。

P 多行打印命令,同 d 和 D 之间的区别一样,P(大写)命令和单行打印命令 p(小写)不同,对于具有多行数据的缓冲区来说,它只会打印缓冲区中的第一行,也就是首个换行符之前的所有内容。

示例:

1、使用正则定址,找到包含happy 的行,读取下一行删除

Linux文本处理工具_文件比对_160

2、使用正则定址,找到包含happy 的行,读取下一行合并为一行处理,将换行符\n替换为空格

Linux文本处理工具_正则表达式_161

3、两行合为一行处理,删除第一个换行符之前的内容(包含换行符)

Linux文本处理工具_文本处理_162

4、两行合为一行处理,打印第一个换行符之前的内容

Linux文本处理工具_正则表达式_163

5、两行合为一行处理,每一行都打印

Linux文本处理工具_文本处理_164

注意:这里合并的行打印了两次,所以第4 个示例中P 的作用是仅打印第一次打印时第一个换行符之前的内容,第二次打印原样输出

6、删除文件内容倒数第二行

Linux文本处理工具_文件比对_165

7、删除文件内容最后两行

Linux文本处理工具_Linux三剑客_166

分支和测试

一般情况下,sed 是将编辑命令从上到下依次应用到读入的行上,但是像d/n/D/N命令都能够在一定程度上改变默认的执行流程,甚至利用N/D/P三个命令可以形成一个强大的循环处理流程。除此之外,其实sed还提供了分支命令b(branch)和测试t(test)两个命令来控制流程,这两个命令可以跳转到指定的标签(label)位置继续执行命令。标签是以冒号:开头的标记,如下例中的:top标签。

分支branch

跳转的位置与标签相关联。

如果有标签则跳转到标签所在的后面行继续执行。

如果没有标签则跳转到脚本的结尾处。

标签:以冒号开始后接标签名,不要在标签名前后使用空格。

准备测试文件:

Linux文本处理工具_字符编码_167

示例:

1、设定:top标签,搜索seker 替换为blues,如果搜索到了seker,分支跳转到:top标签,执行标签后面的脚本

Linux文本处理工具_文件比对_168

2、设定:end标签,搜索seker 替换为blues,如果搜索到了seker,分支跳转到:end标签,执行标签后面的脚本,跳过中间的脚本

Linux文本处理工具_文本处理_169

测试test

测试命令也会更改执行流程,会根据 s 替换命令的结果,如果匹配并替换成功,则脚本的执行会跳转到指定的标签;反之,t 命令无效。测试命令使用与分支命令相同的格式

准备测试文件:

Linux文本处理工具_文本处理_170

示例:

1、查找关键词替换,如果匹配并替换成功则跳过t后面一条命令

Linux文本处理工具_文本处理_171

2、与标签关联,跳转到标签位置

Linux文本处理工具_文件比对_172

cut

cut 命令用于显示文件指定的列或字段,处理内容是以行为单位的,然而在处理多空格相连的内容时,可能会比较吃力一点,所以某些时刻需要用awk 来取代

常用选项:

-d 指定分隔字符,与-f 一起使用

-f 根据-d 的分隔字符将内容分成数段,用-f 取出第几段的意思

-c 以字节为单位取出固定字节区间的内容

示例:

1、以:号为分隔符,取出PATH 变量的第 2段

Linux文本处理工具_文件比对_173

2、以:号为分隔符,取出PATH 变量的第1 段和第3 段

Linux文本处理工具_Linux三剑客_174

3、export 输出全局变量,cut 以字节为单位取出第12 个字节及以后的内容

Linux文本处理工具_正则表达式_175

4、export 输出全局变量,cut 以字节为单位取出第12 - 15 个字节的内容

Linux文本处理工具_文本处理_176

5、查看系统最近登入用户的信息,提取用户名

Linux文本处理工具_字符编码_177

结合前面sed 所学的用法,删除最后两行

Linux文本处理工具_文本处理_178

如果我要提取第三栏,也就是登入用户的ip 地址,这时候用cut 命令就比麻烦了,因为中间不止一个空格

Linux文本处理工具_正则表达式_179

这个时候用awk 更合适

Linux文本处理工具_正则表达式_180

sort

sort 命令的作用是排序,对标准输出内容排序,原始文件不改变。

常用选项:

-f 忽略大小写差异

-b 忽略最前面的空白字符部分

-M 以月份的名字来排序,例如:JAN、DEC 等等的排序方法

-n 使用纯数字排序,默认是用文本排序

-r 反向排序(降序)

-u 在输出行中删除重复的行

-t 指定分隔符,默认是用tab 键分隔

-k 以哪个字段来进行排序的意思

示例:

1、对文件内容排序,忽略大小写

Linux文本处理工具_文本处理_181

2、忽略最前面的空白字符部分,对内容排序

Linux文本处理工具_文本处理_182

3、以月份的名字进行排序

Linux文本处理工具_文本处理_183

4、以纯数字进行排序

Linux文本处理工具_文件比对_184

5、反向排序

Linux文本处理工具_Linux三剑客_185

6、排序输出去重

Linux文本处理工具_正则表达式_186

7、指定分隔符为空格,根据第三个字段进行排序

Linux文本处理工具_Linux三剑客_187

uniq

uniq 命令用来去除重复的行,对重复的行仅列出一个,但是对于不连续的重复行不能去重,因此常与sort 命令配合使用。

常用选项:

-i 忽略大小写的差异

-c 统计发生重复的次数

示例:

1、忽略大小写差异去重

Linux文本处理工具_Linux三剑客_188

2、统计重复出现的行

Linux文本处理工具_Linux三剑客_189

wc

wc 命令可以用来对一个文件或标准输出统计单词数,行数,字节数和字符数。

常用选项:

-l 仅统计行数

-w 仅统计单词(word)数

-c 仅统计字节(byte)数

-m 仅统计字符(character)数

示例:

1、统计行数

Linux文本处理工具_文件比对_190

2、统计单词数

Linux文本处理工具_文件比对_191

3、统计字节数

Linux文本处理工具_字符编码_192

4、统计字符数

Linux文本处理工具_字符编码_193

tee

对于一段标准输出,默认是打印在屏幕上,你可以把这段输出重定向到文件中,但是这样就不会在屏幕上打印输出内容了,如果你既要重定向输出到文件,又要把输出内容打印在屏幕上,可以用tee 命令实现,他就像一个三通管道。

Linux文本处理工具_文件比对_194

常用选项:

-a 以追加(append)的方式写入内容到文件,默认是覆盖(overwrite)

示例:

1、重定向输出到文件,并打印在屏幕上

Linux文本处理工具_正则表达式_195

2、以追加的方式重定向输出到文件,并打印在屏幕上

Linux文本处理工具_字符编码_196

tr

tr 可以用来删除文本当中的一段内容,或者进行替换,虽然tr 命令不支持正则表达式,但它提供了类似的功能,可以用于字符转换、删除和压缩。

常用选项:

-d 后面可以跟一段内容,进行删除

-s 对于连续重复出现的字符进行压缩,只保留一个

示例:

1、删除文本内容中的一段字符串

Linux文本处理工具_文件比对_197

注意:tr 不能单独使用,需要配合管道符|或者重定向输入符号<,不会更改文件的原始内容

2、针对文件每一行进行压缩,即当存在连续重复的字母时只保留一个,下面展示三种写法

Linux文本处理工具_文件比对_198

3、将文本内容中的大写字母转换为小写,下面展示多种写法

Linux文本处理工具_文本处理_199

Linux文本处理工具_文件比对_200

Linux文本处理工具_正则表达式_201

Linux文本处理工具_文本处理_202

4、删除文本中的所有数字后打印到屏幕上

Linux文本处理工具_文件比对_203

7、在相当长的一段时间里,Windows 系统中的文本内容一直使用^M$符号作为换行符,它是一个隐藏字符,而Unix-like 系统使用$作为换行符,如果你经常需要在这两种操作系统之间传文件,需要使用dos2unixunix2dos命令转换换行符的格式。那么,除了dos2unix 命令可以做到把Windows 系统的换行符转换为Unix 格式,tr 命令也可以做到,参照下面这条命令即可

# cat file.txt | tr -d '\r' > file.txt

\r表示的就是^M符号

当然如果你的Windows 操作系统一直保持更新,现在也默认使用$符号换行了

col

col 命令的英文全称是“colation”,其中文释义就是“过滤”。该命令是一个标准输入文本过滤器,它从标注输入设备读取文本内容,并把内容显示到标注输出设备。 在许多UNIX 说明文件里,都有RLF 控制字符。当我们运用shell 特殊字符”>”和”>>”,把说明文件的内容输出成纯文本文件时,控制字符会变成乱码,col 指令则能有效滤除这些控制字符。

常用选项:

-x 将Tab 键转换成对等的空格键

-b 过滤掉所有的控制字符,包括RLF 和HRLF

-f 滤除RLF 字符,但允许将HRLF 字符呈现出来

示例:

1、将文本内容中的Tab 键转换为多个空格

Linux文本处理工具_文件比对_204

^I表示为一个Tab 键,两个Tab键即是^I^I啦,空格键用cat -A 是看不出来的。

2、将col 的man 手册保存为col_man 文件,滤除所有的控制字符

Linux文本处理工具_文件比对_205

注意观察滤除前和滤除后的字节数。

3、将man 的man 手册保存为man_help 文件,滤除RLF 字符,但允许将HRLF 字符呈现出来

Linux文本处理工具_文本处理_206

可见man 的man 手册没有HRLF 字符。

join

join的连接操作简言之就是将两个具有相同域的纪录给挑选出来,再将这些纪录所有的域放到一行。

注意:join在对两个文件进行连接时,两个文件必须都是按照连接域排好序的,按其他域排序是无效的。

语法格式:join [选项] [文件1] [文件2]

常用选项:

-t 指定域的分隔符,默认是空格

-i 忽略大小写的差异

-1-2 -1 用来设置文件1 连接的域,-2 用来设置文件2 连接的域,即设置要用哪个字段来分析的意思

-a1-a2 除了显示共同的记录之外,-a1 显示第一个文件没有共同域的记录,-a2 显示第二个文件中没有共同域的记录

-v1-v2 不显示共同域的记录之外,-v1显示第一个文件没有共同域的记录,-v2显示第二个文件中没有共同域的记录

-o 设置结果显示的格式

示例:

准备测试文件:

Linux文本处理工具_字符编码_207

1、将两个文件的具有共同域的纪录连接在一起

Linux文本处理工具_文件比对_208

注意观察指定分隔符与不指定分隔符的区别。

2、将两个文件的具有共同域的纪录连接在一起,忽略大小写差异

Linux文本处理工具_Linux三剑客_209

3、指定分隔符为:,设定第一个文件连接的域是第二个字段,第二个文件连接的域也是第二个字段

Linux文本处理工具_文本处理_210

注意观察输出结果,23出现了两次,后面连接第二个文件的内容均是D 行的内容,说明join 命令是以第一个文件的域作为关键词去第二个文件查找相应的值。

4、除了显示共同的记录之外,分别显示第一个与第二个文件没有共同域的记录

Linux文本处理工具_字符编码_211

4、不显示共同的记录之外,分别显示第一个与第二个文件没有共同域的记录

Linux文本处理工具_文件比对_212

5、设置结果显示的格式,指定分隔符为:号,将第一个文件的第1、第2、第4、第5和第二个文件的第3个字段连接起来

Linux文本处理工具_字符编码_213

注意观察两条命令的写法与输出结果的区别。

paste

paste 可以直接把两个文件同一行的内容贴在一起,相比于join 要简单多了,不需要比对两个文件的关联字段。

语法格式:paste [选项] [文件1] [文件2]

常用选项:

-d 指定分隔字符,只能接一个字符,默认是以Tab 键分隔的

- 如果文件名写成减号-,表示来自stdin(标准输入)的内容

示例:

1、将两个文件同一行的内容贴在一起

Linux文本处理工具_正则表达式_214

2、指定分隔符为+

Linux文本处理工具_字符编码_215

3、将来自标准输入的内容与文件内容贴在一起

Linux文本处理工具_文本处理_216

Linux文本处理工具_文本处理_217

expand

除了col 命令可以把文本内容中的Tab 键转换成空格键,还有expand 命令也可以做到,且expand 还可以指定一个Tab 键相应地转换多少个空格键,并且通过unexpand 还可以把空格键转换成Tab 键。

常用选项:

-t 后面接数字,表示一个Tab 键相应地转换为多少个空格键。一般来说,一个Tab 键对应8 个空格键。

示例:

1、过滤/etc/man_db.conf 文件中开头以MAN 开头的行,提取前6 行,将Tab 键转换为空格

Linux文本处理工具_文件比对_218

2、指定一个Tab 键相应地转换为4 个空格键

Linux文本处理工具_Linux三剑客_219

上面的expand -t 4 - < ttt1.txt 相当于cat ttt1.txt | expand -t 4,都是把标准输出重定向给expand 命令,其实expand 后面可以直接写文件名,即可以写成expand -t 4 ttt1.txt

3、将空格转换为Tab 键

Linux文本处理工具_字符编码_220

unexpand 这个命令比较奇怪,必须要指定-t选项才会转换生效,而expand 命令如果不指定-t选项默认就是转换为8 个空格。

split

split 可以把一个大文件,根据文件大小或者行数来分割,就可以把一个大文件分割成几个小文件了。

语法格式:split [选项] [文件名] PREFIX

PREFIX 即文件名前缀,分割后的文件以PREFIXaa,PREFIXab,PREFIXac ... 这样的方式命名。

常用选项:

-b 后面接文件大小的单位如b,k,m等,表示希望分割的文件大小

-l 以行数来进行分割,默认是1000 行

-d 使用数字后缀而不是字母,即PREFIX01、PREFIX02、PREFIX03 ...  这样的方式 

示例:

1、将/etc/services 文件分割成小文件

Linux文本处理工具_字符编码_221

默认是按行数来分割,1000 行一个文件。

2、按大小分割,例如300k 一个文件

Linux文本处理工具_文件比对_222

3、按行数分割,例如3000 行一个文件

Linux文本处理工具_文本处理_223

4、分割后的文件名使用数字后缀而不是字母

Linux文本处理工具_字符编码_224

5、对标准输出内容进行分割

Linux文本处理工具_文本处理_225

xargs

-0 数字零,如果输入的stdin 含有特殊字符,例如` ' , \ 空格键等等字符,这个-0选项可以把它还原成为一般字符,每个字符都是字面意思,当输入项可能包含空格、引号或反斜杠时非常有用。

-e 这个是EOF(end of file)的意思,后面可以接一段字符串,当xargs 识别到这个字符串时,就会停止继续工作。

-p 在执行每个指令的argument(参数)时,都会询问用户是否执行。

-n 后面接次数,每次command 指令执行时,要使用几个参数的意思。

当xargs 后面没有接任何指令时,默认是以echo 来进行输出。

示例:

1、向id 命令传递参数,查看多个用户的id 信息

Linux文本处理工具_正则表达式_226

可以看到id 命令是支持一次性接收处理多个用户名的,但是通过管道符|却只传递了第一个参数,通过xargs 可以向id 传递这三个用户名。

2、遇到特殊符号按一般字符处理

Linux文本处理工具_文本处理_227

这里的换行符\n被当做一般字符处理了,相当于执行了id root\nbin\ndaemon,系统中不存在这个用户。

3、指定EOF 字符为daemon,当xargs 识别到这个字符时停止继续传递参数

Linux文本处理工具_字符编码_228

注意:这里-e选项与后面接的字符串之间不能有空格,可以用引号引起来。

4、每次执行指令时询问用户是否执行

Linux文本处理工具_Linux三剑客_229

5、xargs 每次传递一个参数,配合-p 使用看得更清楚

Linux文本处理工具_Linux三剑客_230

每次执行指令时需要用户输入yn决定是否执行,也可以输入yesno

6、xargs 后面不接指令,默认以echo 输出

Linux文本处理工具_Linux三剑客_231

7、xargs 还有一个非常好用的功能,就是对于不支持管道符传递参数的命令,xargs 可以帮助他们进行传参,例如systemctl 这个命令

Linux文本处理工具_字符编码_232

关于减号“-”的用途

管道符|给命令传递参数在bash 的连续处理程序中是相当重要的,另外,在管道命令当中,常常会使用一个命令的stdout(标准输出)作为这次的stdin(标准输入),某些命令需要用到文件名称(例如tar)来进行处理时,该stdin 与stdout 就可以用减号-替代,举例来说:

Linux文本处理工具_正则表达式_233

上面这个例子是说:我把/root 目录归档,但不是归档到文件,而是传递到了stdout,经过管道符|后,传递给了后面的命令tar -xf -,后面的这个-则是调用前一个命令的stdout,因此,我们就不需要使用文件名了,这是个很常见的用法。

printf

在很多时候,我们可能需要将内容格式化输出,如果你需要自己编写一些程序的话,printf 可以帮助你在屏幕上漂漂亮亮地输出。

语法格式:printf [列打印格式] [实际内容]

关于格式方面的几个特殊样式:

\a 警告声音退出

\b 退格键(BackSpace)

\f 清除屏幕(form feed)

\n 换行符

\r 亦即Enter 键

\t 水平的Tab 键

\v 垂直的Tab 键

\xNN NN 为两位数的数字(hexadecimal value,十六进制值),可以转换为字符

关于C 程序语言内,常见的变量格式:

%ns 那个n 是数字,s 代表string,亦即多少个字符

%ni 那个n 是数字,i 代表integer,亦即多少个整数位数

%N.nf 那个n 与N 都是数字,f 代表floating(浮点),如果有小数位数,假设我总共要十个位数,小数点后面保留两位,即为%10.2f

示例:

例如我想要输出下面的样式:

Linux文本处理工具_正则表达式_234

上面的内容主要分成5 个字段,各个字段之间可使用Tab 或空格键分隔。

格式化输出score.txt 文件的内容:

Linux文本处理工具_正则表达式_235

由于printf 并不是管道命令,因此我们得要通过$(command)这样的方法把括号内的命令先执行,或写成`command`这种形式,把文件内容先提取出来交给printf 作为后续的实际内容,%s代表一段不固定长度的字符串,\t代表Tab 键,我们把字符串之间用Tab 键分隔,由于\t 与%s 之间还有一个空格,因此每段字符串之间会有一个Tab 键和一个空格键分隔。

然而通过上面的格式输出,效果并不如意,行与行之间的字段出现了错位。

既然每个字段的长度不固定会造成上述的困扰,那我们将每个字段固定好了,写法类似于C 语言:

Linux文本处理工具_正则表达式_236

%10s代表的是一段长度为10 个字符的字符串栏位,%5i代表的是长度为5 个字符的整数栏位,%8.2f代表的是长度为8 个字符的浮点数栏位(包含小数点和小数),其中小数占2 个字符长度。

printf 除了可以格式化输出以外,还可以根据ASCII 码表中的数字与字符的对应关系来显示内容。

举例来说:16 进制位的45 对应ASCII 码表中的什么字符呢?

Linux文本处理工具_字符编码_237

是字母E 啦,我们来查看一下ASCII 码表是不是这样的:

Linux文本处理工具_字符编码_238

奇怪了,字母E 对应的ASCII 值明明是69 啊,这是因为ASCII 码表中的值是十进制的,我们把十六进制的45 转换成十进制的数值就是69 啦!

Linux文本处理工具_正则表达式_239

如果你喜欢的女孩子也是电子信息、计算机行业的,工作有接触Linux,可以把下面这段代码给她执行一下:

# printf '\x49\x20\x6C\x6F\x76\x65\x20\x79\x6F\x75\x21\n'

Linux文本处理工具_文本处理_240

男孩子要勇敢一点!加油!!!

文件比对工具

diff

什么时候会用到文件比对?通常在同一个软件的不同版本之间,比较配置文件的差异。很多时候所谓的文件比对,通常是用在ASCII 纯文本文件(ASCII text)上的。那么比对的命令中最常见的就是diff,除了diff 比对之外,还可以借由cmp 命令来比对非纯文本文件,同时,也能够借由diff 建立的分析文件,处理补丁(patch)功能的文件。

语法格式:diff [选项] [FILES]

FILES 可以用减号- 代替,表示stdin(标准输入)的意思。

常用选项:

-b 忽略一行内容中,仅有多个空格的差异(例如:“about me”与“about     me” 视为相同)

-B 忽略空行的差异

-i 忽略大小写的差异

-q 仅判断两个文件是否不同

--brief 仅判断两个文件是否不同

-r 递归处理所有子文件

-t 将制表符视为空格

准备测试文件:

Linux文本处理工具_文本处理_241

Linux文本处理工具_Linux三剑客_242

示例:

1、比对两个文本文件

Linux文本处理工具_字符编码_243

简单解读一下上面的比对结果:diff 把两个文本文件内容的差异列了出来,中间用三个减号-画一条横线分隔对两个文件的内容以做区分,1,2c1表示第一个文件的第1 行和第2 行与第二个文件的第1 行不同,下面用符号<表示左边文件的内容,>表示右边文件的内容,接着用4,5c3,4表示第一个文件的第4 行和第5 行与第二个文件的第3 行和第4 行不同,7d5表示以左边文件的第7 行为基准,右边文件的第5 行删除了这一行内容,下面用<显示了左边文件被删除的内容。

将两个文件的顺序调转一下执行看看:

Linux文本处理工具_文本处理_244

很直观地可以看到两次执行结果的差异,最后那个5a7中的a表示增加的意思,如果是d就是删除。

2、忽略一行内容中,仅有多个空格的差异

Linux文本处理工具_Linux三剑客_245

3、忽略空行的差异

Linux文本处理工具_正则表达式_246

可以看到与示例1 的执行结果并没有任何差异,博主对这个-B 选项的用法意义不明,也许不是这么用的,这是个反面教材。

4、忽略大小写的差异

Linux文本处理工具_文件比对_247

5、仅判断两个文件是否不同

Linux文本处理工具_文件比对_248

可以看到如果两个文件的内容是相同的屏幕上不会有任何打印。

-q--brief选项的功能是完全一样的:

Linux文本处理工具_字符编码_249


6、递归处理所有子文件

Linux文本处理工具_文件比对_250

这里的-r参数怎么理解呢?他比对的其实不是文件里面的内容,而是目录下的文件名,因为每个文件名都是独一无二的,所以都会列出来。

7、将制表符视为空格

Linux文本处理工具_文本处理_251

通过cat -A 可以看到输出结果的差异。

cmp

相对于diff 的广泛用途,cmp 似乎就用的没有这么多了,cmp 主要也是在比对两个文件,他主要是以字节(byte)为单位逐个去比对,因此,不仅可以比对文本文件,也可以比对二进制(binary file)文件。diff 主要是以行为单位比对,cmp 则是以字节为单位去比对,这一点要注意。

语法格式:cmp [选项] [文件1] [文件2]

常用选项:

-l 将有差异的字节都列出来。cmp 默认仅会输出第一个发现的不同点。

示例:

1、比对两个文本文件,这里依然用diff 章节的测试文件

Linux文本处理工具_文本处理_252

在第一行的第7 个字节开始发现了不同。

2、将有差异的字节都列出来

Linux文本处理工具_正则表达式_253

好家伙,输出的内容真不少,看着令人头大!

3、比对两个二进制文件

Linux文本处理工具_字符编码_254

patch

语法格式:patch [选项] [源文件] [补丁文件]

常用选项:

-p 后面可以接【取消几层目录】的意思

-R 代表还原,将新的文件版本还原成原来旧的版本

patch 这个命令与diff 有密不可分的关系,我们前面提到,diff 可以用来分辨两个版本之间的差异,举例来说,刚刚我们建立的text1 与text2 之间就是两个不同版本的文件。那么,如果要升级呢?就是把text1 文件升级到text2 版本。

我们可以这样做测试:

1、以家目录下的text1 与text2 文件制作补丁文件

Linux文本处理工具_字符编码_255

一般来说,使用diff 制作出来的比对文件通常使用后缀名.patch,至于内容就如同上面的样子,基本上就是以行为单位,看看哪边有一样和不一样的,找到一样的地方,然后把不一样的地方替换。

那么如何把旧的文件版本更新到新的版本呢,就是把text1 改成与text2 的内容相同,可以这样做:

Linux文本处理工具_文本处理_256

为什么这里会使用-p0呢?因为我们在比对新旧版的文件时是在同一个目录下,因此不需要减去目录啦。如果是使用绝对路径比对(diff 旧目录 新目录)时,就要根据建立patch 文件所在目录来进行目录的删减。

2、如果要恢复text1 文件到旧的版本可以这样做:

Linux文本处理工具_文件比对_257

vimdiff

vimdiff 相比于diff 命令可以让你更直观地看到两个文件之间的差异,非常好用!

语法格式:vimdiff [选项] [文件1] [文件2]

示例:

1、比对text1 与text2 文件

Linux文本处理工具_文本处理_258

不同之处有高亮显示,非常直观!退出的方式跟普通的vim编辑器退出的方式一样,使用:q,不过要执行两次,第一次退出text1 文件,第二次退出text2 文件。

pr

pr 命令用来将文本文件转换成适合打印的格式,它可以把较大的文件分割成多个页面进行打印,并为每个页面添加标题。

语法格式:pr [选项] [文件]

常用选项:

-h 为页指定标题

准备测试文件:

Linux文本处理工具_Linux三剑客_259

示例:

1、打印文件内容

Linux文本处理工具_字符编码_260

可以看到pr 命令给文件内容增加了标头,有日期和时间、有文件和页码,下面还有很多空行,图中没有表现出来。

2、为页指定标题

Linux文本处理工具_文本处理_261

iconv

iconv命令是 Linux 系统自带的用于转换文件编码的命令行工具。

语法格式:iconv -f 原始编码 -t 新编码 文件名 [-o 新文件]

常用选项:

--list 列出iconv 支持的编码格式

-f from,亦即来源之意,后面接原始编码

-t to,亦即要转换成为的编码格式

-o 如果要保留源文件,那么使用-o ,后面接新文件

常见的编码格式:

big5 繁体中文

gb2312 简体中文

gbk 一种针对汉字的字符编码标准,它是基于GB2312-1980的扩展,也被称为GBK/GB2312

utf8 一种通用的字符编码标准,它可以将世界上所有的字符(包括各种语言的文字、标点符号、数字、符号等)转换为计算机可以识别和存储的二进制数字

下面我们用Windows 系统,通过NotePad++ 编辑器写一个big5 编码格式的文本文件,内容如下:

Linux文本处理工具_文件比对_262

把他上传到服务器,查看一下这个文件:

Linux文本处理工具_文本处理_263

显示乱码,因为我使用的ssh 远程连接工具SecureCRT 默认使用的是UTF-8 编码格式,把他调整为Big5,再来看看:

Linux文本处理工具_文件比对_264

Linux文本处理工具_Linux三剑客_265

1、将big5.txt 文件转换成utf8 编码格式

Linux文本处理工具_字符编码_266

可以看到,两个文件有明显的不同,我们把终端的编码格式改回utf8

Linux文本处理工具_Linux三剑客_267

现在可以正常看到utf8.txt 文件的内容了

Linux文本处理工具_正则表达式_268

2、如果我要把繁体中文转换为简体中文,这就有点麻烦了,不可以直接转换,需要先把big5 编码格式的文件转换为utf8 格式,再转换为gb2312 格式,最后转换为utf8 格式

Linux文本处理工具_文本处理_269

3、如果源文件也是utf8 编码格式的,内容是繁体中文,需要转换成utf8 格式的简体中文,也就是我需要把utf8 格式的繁体中文转换成utf8 格式的简体中文,通过下面这条命令可以做到:

# iconv -f utf8 -t big5 fanti.txt | iconv -f big5 -t gb2312 | iconv -f gb2312 -t utf8 -o jianti.txt

参阅

Linux三剑客之awk命令 - 琴酒网络 - 博客园

sed入门详解教程 - 肖邦linux - 博客园

sed模式空间(pattern space)和保持空间(hold space)_sed pattern space hold sace-CSDN博客

sed的模式空间和保持空间 - LiuYanYGZ - 博客园

sed高级命令 - Wangjingjing - CSDN博客

sed高级命令 - 汪泽文666 - CSDN博客

[sed] 分支&测试 - 范云龙 - 博客园

sed测试命令-CSDN博客

sed高级的流控制命令-CSDN博客

鳥哥私房菜 - 第十章、認識與學習BASH —— 管線命令 (pipe)

鳥哥私房菜 - 第十一章、正規表示法與文件格式化處理

Road 2 Coding —— 正则表达式

Linux----tr命令详细使用方法_linux tr-CSDN博客

col命令 – 用于过滤控制字符 – Linux命令大全(手册)

RLF、HRLF控制字符到底是什么 - Dog17 - 博客园

join命令 – 连接两个文件 – Linux命令大全(手册)

diff命令 – 比较文件内容差异 – Linux命令大全(手册)

pr命令 – 将文本文件转换成适合打印的格式 – Linux命令大全(手册)

鳥哥私房菜 - 9.4.3 語系編碼轉換: iconv

iconv命令 – 转换文件编码 – Linux命令大全(手册)