Linux深入探索09-过滤器

----- 最近更新【2022-01-15】-----

本文目录结构预览:

  • 一、简介
  • 二、实用的过滤器(列表)
  • 三、简单的过滤器:cat、split、tac、rev、head、tail
    1、cat - 复制数据到标准输出
    2、split - 划分文件
    3、tac - 行反转
    4、rev - 字符反转
    5、head - 查看开头
    6、tail - 查看末尾
  • 四、比较不同:cmp、comm、diff、sdiff
    1、cmp - 比较两个文件(二进制或者文本)
    2、comm - 比较两个文件(有序文本)
    3、diff - 比较两个文件(文本)
    4、sdiff - 比较两个文件(并排比较)
  • 五、抽取:cut、colrm、paste
    1、cut - 抽取指定列
    2、colrm - 移除列
    3、paste - 组合数据列
  • 六、统计和格式化:nl、wc、expand、unexpand、old、fmt、pr
    1、nl - 插入行号
    2、wc - 单词统计
    3、expand - 将制表符转换成空格
    4、unexpand - 将空格转换成制表符
    5、fold - 格式化行
    6、fmt - 格式化段落
    7、pr - 按页格式化文本
  • 七、查找:grep、look
    1、grep - 选取包含特定模式的行
    2、look - 选取特定模式开头的行(有序文本)
  • 八、排序、组合及变换:sort、uniq、join、tr、sed
    1、sort - 排序数据
    2、uniq - 查找重复行(有序文本)
    3、join - 合并两个文件中的数据(有序文本)
    4、tr - 改变或者删除指定的字符
    5、sed - 非交互文本编辑
  • 九、分页程序:less、more
  • 十、参考

一、简介

过滤器 就是任何能够从标准输入读取文本数据并向标准输出写入文本数据(每次一行)的程序。之前介绍的管道|命令主要就是结合过滤器来完成工作,但是管道线中的第一个和最后一个程序不必是过滤器。

过滤器每次一行地从标准输入读取数据,完成处理后,将结果每次一行地写到标准输出。

二、实用的过滤器(列表)

过滤器 作用 备注
awk 编程语言:操作文本
cat 组合文件:复制标准输入到标准输出
colrm 删除指定的数据列
comm 比较两个有序文件,显示区别
cmp 比较两个文件
cut 从数据中抽取指定列(字段)
diff 比较两个文件,显示不同
expand 将制表符转变成空格
fold 将长行格式化成较短的行
fmt 格式化段落,从而使它们看上去更漂亮
grep 选择包含指定模式的行
head 从数据的开关选择行
join 基于公用字段,组合数据列
look 选择以指定模式开头的行
nl 创建行号
paste 组合数据列
perl 编程语言:操作文本、文件、进程
pr 将文本格式化为页或者列
rev 每行数据中的字符反序排列
sdiff 比较两个文件,显示区别
sed 非交互式文本编辑
sort 排序数据;检查数据是否有排序
split 将大文件分隔成较小的文件
strings 在二进制文件中搜索字符串
tac 组合文件,同时将文本行的顺序反转
tail 从数据的末尾选择行
tr 改变或者删除指定的字符
tsort 根据偏序创建全序
unexpand 将空格转变成制表符
uniq 选择重复/唯一行
wc 统计行数、单词数和字符数

注意:

  • 我们常用less命令来显示输出,但less并不是每次一行地将数据写到标准输出。less允许每次一屏地查看所有的数据、向后滚动和向前滚动、搜索具体模式等,所以less不是过滤器。
  • look 不能从标准输入中读取数据,它必须从一个或多个文件中获取输入。所以,严格地讲,look 也不是一个过滤器。
  • more 只能向前分页浏览文件内容,more 也不是一个过滤器。

三、简单的过滤器:cat、split、tac、rev、head、tail

1、cat - 复制数据到标准输出

cat 程序将数据未加改变地复制到标准输出。数据可以来源于标准输入或者一个或多个文件。(concatenate files and print on the standard output.)

语法:cat [OPTION]... [FILE]...

常用例子:

语法 作用
cat > file 从键盘读取数据,创建新文件或者替换已有文件
cat >> file 从键盘读取数据,将数据追加到已有文件中
cat < file 或者 cat file 显示一个已有文件
cat < file1 > file2 复制文件
cat file1 file2 file3 组合多个文件,一次一屏地显示结果
cat file1 file2 file3 > file4 组合多个文件,将输出保存到一个不同文件中
cat file1 file2 file3 | program 组合多个文件,将输出管道传送给另一个程序

cat 命令常用选项:

  • -n,(number) 在每行前面加一个行号
  • -b,(blank) 与 -n 选项一起使用,告诉cat不要对空白行编号
  • -s,(squeeze) 将多个连续空白行替换为一个空白行

2、split - 划分文件

split 将一个大文件划分成几个较小的文件。(split a file into pieces)

语法: split [OPTION]... [FILE [PREFIX]]

常用组合:split [-d] [-a num] [-l lines] [file [prefix]]

  • -a num,num是创建文件名时用作文件名后缀的字符或数字的数量,默认是aa、ab、ac...
  • -d,(digits)使用数字作为文件名后缀,默认从00开始。
  • -l lines,lines是每个新文件所包含的最大行数,默认是1000。
  • file,输入文件的名称。
  • prefix,输出文件名称的前缀,默认是x。

例:

split -d -l 5000 filename newfile_

3、tac - 行反转

tac 在将文本写入到标准输出之前将文本行的顺序反转(名称tac就是cat的反向拼写)。(concatenate and print files in reverse)

语法:tac [OPTION]... [FILE]...

例:

tac file1 fiel2 file3 | less

4、rev - 字符反转

rev 将文本各行中字符的顺序反转。(reverse lines characterwise)

语法:rev [option] [file...]

例:

rev filename | tac

5、head - 查看开头

head 从数据的开头选择数据行。(output the first part of files)

语法:head [OPTION]... [FILE]...

常用选项:

  • -n,(lines)希望选取的数据行的数量,默认是开头10行。

例:

[nosee@instance-4 ~]$ cal -y | head
                            2022
      January               February               March          
Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  
                   1         1  2  3  4  5         1  2  3  4  5  
 2  3  4  5  6  7  8   6  7  8  9 10 11 12   6  7  8  9 10 11 12  
 9 10 11 12 13 14 15  13 14 15 16 17 18 19  13 14 15 16 17 18 19  
16 17 18 19 20 21 22  20 21 22 23 24 25 26  20 21 22 23 24 25 26  
23 24 25 26 27 28 29  27 28                 27 28 29 30 31        
30 31 

6、tail - 查看末尾

tail 从数据的末尾选择数据行。(output the last part of files)

语法:tail [OPTION]... [FILE]...

常用选项:

  • -n num,(lines)希望选取的数据行的数量,默认是末尾10行。
  • -n +num,从num行开始,显示至文件末尾
  • -f,(follow 跟随)监听一个文件末尾的变化。(如,实时监控日志文件。ail 也可以同时监控多个文件)

例:

cat file1 file2 file3 | sort | tail -n 20

例:实时监控日志文件

# 窗口1
tail -f day1
# 窗口2 (模拟日记文件添加日志)
cat >> day1

四、比较不同:cmp、comm、diff、sdiff

1、cmp - 比较两个文件(二进制或者文本)

cmp 的使用情况只有一种情形:查看两个文件是否相同。( compare two files byte by byte)

语法:cmp [OPTION]... FILE1 [FILE2 [SKIP1 [SKIP2]]]

cmp 程序逐字节地比较两个文件,查看两个文件是否相同。如果两个文件中对应的字节完全相同,那么这两个文件就是相同的,在这种情况下,cmp 程序不做任何处理(没有消息就是好消息)。如果两个文件不相同,那么 cmp 程序就显示一个合适的消息。

例:

[nosee@instance-4 ~]$ cmp test1 test2
test1 test2 differ: byte 1, line 1

2、comm - 比较两个文件(有序文本)

comm 程序一行一行地比较两个有序的文本文件。当有两个相似的文本,并且希望查看它们之间的区别时,可以使用 comm 程序。(compare two sorted files line by line)

语法:comm [OPTION]... FILE1 FILE2

comm 程序以3列显示输出:第1列包含只在第一个文件中有的行;第2列包含只在第二个文件中有的行;第三列包含两个文件中都有的行。

例:

[nosee@instance-4 ~]$ cat > file1
1.aaaaa
2.ddddd
3.ggggg
4.nnnnn
^C
[nosee@instance-4 ~]$ cat > file2
1.aaaaa
2.bbbbb
3.ggggg
^C
[nosee@instance-4 ~]$ comm file1 file2
		1.aaaaa
	2.bbbbb
2.ddddd
		3.ggggg
4.nnnnn

常用选项:

  • -1,不输出第1列内容
  • -2,不输出第2列内容
  • -3,不输出第3列内容

如,不想输出相同的内容:

[nosee@instance-4 ~]$ comm -3 file1 file2
	2.bbbbb
2.ddddd
4.nnnnn

3、diff - 比较两个文件(文本)

当需要(1)比较两个无序文件,(2)比较大的文件时,可以使用 diff (compare files line by line)。diff 可以用来查找任何类型的文件带来的区别,例如编程语言等。可以联想到 Git(版本控制系统)。

1)语法:diff [OPTION]... FILES

如上面的例子使用 diff 比较:

[nosee@instance-4 ~]$ diff file1 file2
2c2
< 2.ddddd
---
> 2.bbbbb
4d3
< 4.nnnnn

diff 的目的就是显示将第一个文件修改为第二个文件所需遵循的指示。这些指示的语法相当简洁,但并不简单。

指示的说明:c(change,改变)、d(delete,删除)、a(append,追加)。每个c、d、a字符的左右两边都有一串行号,左边的数字指第一个文件中的行,右边的数字指第二个文件中的行。< 标记第一个文件中的行,< 标记第二个文件中的行。(---)是为了可读性将两个不同的行隔开。

如,上面例子表示,将第一个文件转换成第二个文件需要:2c2表示将第一个文件的第二行修改成第二个文件的第二行,4d3表示将第一个文件的第4行删除。

2)常用选项

diff 程序相当复杂,它有大量的选项和许多种生成输出的方式。一些常用的选项如下:

  • -i,(case insensitive)不区分大小写。
  • -w,(whitespace)忽略所有空白符。
  • -b,忽略空白符(只忽略数量上的区别)。
  • -B,(blank lines)忽略所有空白行。
  • -q,(quiet)当两个文件不同时,省略所有的细节,只给出文件不同的提示即可。
  • -s,(same)当两个文件相同时,也给出提示信息。
  • -c,(context,上下文关系)以不太简洁,但更容易理解的格式显示两个文件之间的区别。
  • -u,(unified output,统一输出)生成类似于 -c 选项生成的输出,但是没有重复行。
  • -y,(side-by-side)并排显示

3)-c 选项
使用 -c 选项后,diff 将不再显示指示和行号,而是显示存在不同的实际行,同时还显示不同行的上面和下面各两行内容。

[nosee@instance-4 ~]$ diff -c file1 file2
*** file1	2022-01-12 20:52:27.120528503 +0000
--- file2	2022-01-12 20:52:43.161814285 +0000
***************
*** 1,4 ****
  1.aaaaa
! 2.ddddd
  3.ggggg
- 4.nnnnn
--- 1,3 ----
  1.aaaaa
! 2.bbbbb
  3.ggggg

最顶端的两行展示两个文件的信息。同时说明第一个文件由*(星号)字符标志,第二个文件由-字符标志。这两行之后,则示范了为使两个文件相同需要进行些什么改变。
相比默认的输出方式,-c 选项所生成的输出要比默认格式生成的输出冗长很多。

4)-u 选项
生成类似于 -c 选项生成的输出,但是没有重复行。

[nosee@instance-4 ~]$ diff -u file1 file2
--- file1	2022-01-12 20:52:27.120528503 +0000
+++ file2	2022-01-12 20:52:43.161814285 +0000
@@ -1,4 +1,3 @@
 1.aaaaa
-2.ddddd
+2.bbbbb
 3.ggggg
-4.nnnnn

5)-y 选项
生成并排的格式,在这种各式中,第一个文件中的每一行都与第二个文件中的对应行并排着显示。

[nosee@instance-4 ~]$ diff -y file1 file2
1.aaaaa								1.aaaaa
2.ddddd		    			      |	2.bbbbb
3.ggggg								3.ggggg
4.nnnnn						      <

这种类型输出的优点是非常容易看出区别,缺点则是对于长文件来说可能生成太多输出。

该输出模式可以使用sdiff命令来代替diff -y

4、sdiff - 比较两个文件(并排比较)

当需要进行并排比较时,许多人愿意使用sdiff,因为它有许多专用的选项,可以提供大量的控制。(side-by-side merge of file differences)

语法:sdiff [OPTION]... FILE1 FILE2

[nosee@instance-4 ~]$ sdiff file1 file2
1.aaaaa								1.aaaaa
2.ddddd						      |	2.bbbbb
3.ggggg								3.ggggg
4.nnnnn						      <

常用选项:

  • -l,当两个文件拥有共同行时,该选项只显示左边的列。
  • -s,不显示在两个文件中相同的任何行。
  • -w num,改变列的宽度。
  • -i-W-b-B 选项则与 diff 的相同意思。(注意 sdiff 使用 -W,而 diff 使用 -w
[nosee@instance-4 ~]$ sdiff -s -w 30 file1 file2
2.ddddd	      |	2.bbbbb
4.nnnnn	      <

五、抽取:cut、colrm、paste

1、cut - 抽取指定列

cut 程序是一个从数据中抽取指定列(或指定字段)并将其它内容抛弃的过滤器(remove sections from each line of files)。这与 colrm 相反,colrm 从数据中删除指定列并保存其它内容。

语法:cut OPTION... [FILE]...

1)当抽取数据列时
语法:cut -c list [FILE]... 或 -c 后面的空格可以省略。

使用列表告诉 cut 希望抽取哪些列时,可以指定一个或多个列号(用逗号隔开),或者用-来指定列的范围。

例:

[nosee@instance-4 ~]$ cat day
                            2021
      January               February               March          
Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  
                1  2      1  2  3  4  5  6      1  2  3  4  5  6  
 3  4  5  6  7  8  9   7  8  9 10 11 12 13   7  8  9 10 11 12 13  
10 11 12 13 14 15 16  14 15 16 17 18 19 20  14 15 16 17 18 19 20  
17 18 19 20 21 22 23  21 22 23 24 25 26 27  21 22 23 24 25 26 27  
24 25 26 27 28 29 30  28                    28 29 30 31           
[nosee@instance-4 ~]$ cut -c 23-42 day
      2021
      February      
Su Mo Tu We Th Fr Sa
    1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28  

管道应用例子:

[nosee@instance-4 ~]$ who
root     pts/0        2022-01-12 23:20 (120.240.48.86)
nosee    pts/1        2022-01-12 23:20 (120.240.48.86)
nosee    pts/3        2022-01-12 14:32 (34.96.173.249)
[nosee@instance-4 ~]$ who | cut -c1-8 | sort
nosee   
nosee   
root 
[nosee@instance-4 ~]$ who | cut -c1-8 | sort | uniq -c
      2 nosee   
      1 root  

2)当抽取数据字段时
当文本信息不是按列对齐的时候,但如果它是以一个机器可读格式存在,也是可以使用 cut 来抽取的。

当使用程序处理数据时,我们经常会遇到机器可能的文件,如unix的口令文件/etc/passws,如数据库CSV文件。对于这种数据来说,每行都称为一个记录(record),每行的各个部分称为字段(field),而充当字段分隔符的字符称为定界符(delimiter)。

语法:cut -f list [-d delimiter] [-s] [FILE]...,或 -f 与 -d 后面的空格可省略。

例:

[nosee@instance-4 ~]$ cut -f 1,3-5 -d ':' /etc/passwd
root:0:0:root
daemon:1:1:daemon
bin:2:2:bin
sys:3:3:sys
sync:4:65534:sync
games:5:60:games
man:6:12:man
lp:7:7:lp
mail:8:8:mail

2、colrm - 移除列

colrm("column remove",移除列)程序从标准输入读取数据,删除指定的数据列,然后将剩余数据写入到标准输出。(remove columns from a file)

语法:colrm [start [stop]]

其中start和stop指定要移除区域的开头和末尾,列的编号从1开始。

例:

colrm 14 15 < filename | less
colrm 14 15 < file1 > file2

3、paste - 组合数据列

paste 程序组合数据列。 (merge lines of files)
paste 程序可以将几个文件(其中每个文件都包含一列数据)组成一个大表;也可以将连续的数据行组合起来,构建多个列。

语法:paste [OPTION]... [FILE]...

例:

paste fime1 file2 file3 > info.txt

六、统计和格式化:nl、wc、expand、unexpand、old、fmt、pr

1、nl - 插入行号

在文本中插入行号。(number lines of files)

语法:nl [OPTION]... [FILE]...

常用选项:

  • -v num,起始号
  • -i num,增量
  • -b a,(body numbering)正文编号。后面跟字母a(all lines),对所有行编号。(默认情况下 nl 不对空行编号)
  • -n,(number format)数字格式。后面可跟:ln(左对齐,没有前导0)、rn(右对齐,没有前导0)、rz(右对齐,有前导0)

例:

[nosee@instance-4 ~]$ nl -b a -n rz aaa.txt | head
000001	NL(1)                              User Commands                               NL(1)
000002	
000003	NAME
000004	       nl - number lines of files
000005	
000006	SYNOPSIS
000007	       nl [OPTION]... [FILE]...
000008	
000009	DESCRIPTION
000010	       Write each FILE to standard output, with line numbers added.

2、wc - 单词统计

wc 程序统计行、单词和字符的数量。(print newline, word, and byte counts for each file)

语法:wc [OPTION]... [FILE]...wc [OPTION]... --files0-from=F

默认情况下,wc 的输出包含3个数字:数据中的行数、单词数和字符数。

  • “行”就是以新行字符结尾的一串字符
  • “单词”就是一串连续的字符,用空格、制表符或新行字符分隔
  • “字符”就是字母、数字、标点符号、空格、制表符或者新行字符

常用选项:

  • -l,统计行
  • -w,统计单词
  • -c,统计字符
  • -L,显示最长行的长度

例:

[nosee@instance-4 ~]$ wc aaa.txt day.txt 
  94  315 2901 aaa.txt
   8  114  502 day.txt
 102  429 3403 total

例:统计目录下的文件数

[nosee@instance-4 ~]$ ls -al /etc | wc -l
150

3、expand - 将制表符转换成空格

expand 程序将输入文件中的所有制表符改变成空格,并同维持与原始文本相同的对齐方式。(convert tabs to spaces.)

语法:expand [OPTION]... [FILE]...

默认情况下,expand 使用 Unix 惯例,即将制表位设置为每8个位置一个。因此,输入中的每个制表符都将被输出中的1至8个空格替换。

unexpand

  • -t num,设置制表位。默认num为8,即每隔8个字符为一个制表位。
  • -i,(initial)只转换每行开头的制表符

例:

expand -t 4 filename

4、unexpand - 将空格转换成制表符

将空格转换成制表符,同时保持原始文件中的对齐方式。(convert spaces to tabs.)

语法:unexpand [OPTION]... [FILE]...

与 expand 一个重要的区别就是,默认情况下 unexpand 程序只替换行开头的空格。

常用选项:

  • -a,(all)替换所有空格

5、fold - 格式化行

fold 将长行分隔成短行。(wrap each input line to fit in specified width)

语法:fold [OPTION]... [FILE]...

常用选项:

  • -w width,设置行的最大宽度,默认是80。
  • -s,不分隔单词

例:

man fold | fold -s -w 40 | less

6、fmt - 格式化段落

fmt 程序将段落中的各行连接起来,从而使段落尽可能短小和紧凑,而且还不改变内容和空白符。换句话说,就是 fmt 使用文本看上去更漂亮。(simple optimal text formatter)

语法:fmt [-WIDTH] [OPTION]... [FILE]...

常用选项:

  • -w num,设置行的宽度。(default of 75 columns)
  • -u,(uniform spacing)减少空格,使单词之间最多只有一个空格,句子末尾最多只有两个空格。
  • -s,(split only)仅拆分。告诉 fmt 拆分长行,但是不连接短行。

当 fmt 读取文本时,它假定段落由空行分隔。因此,一个段落就是一个或多个连续的文本行,不包括空行。
fmt 程序根据下述规则每次读取并格式化一个段落:

  • 行宽:使每行尽可能的长,但是不能超过指定的长度。默认情况下,-w 的值为 75 个字符。
  • 句子:无论何时,尽可能地在句子末尾分隔行。
  • 空白符:保持单词与空行之间的所有缩进、空格。可使用 -u 选项修改。
  • 制表符:在读取文件时将所有的制表符转换成空格,并且在最后的输出中的合适位置上插入新的制表符。

例:

[nosee@instance-4 ~]$ man fmt | fmt -u -w 50 | head -n 16
FMT(1) User Commands FMT(1)

NAME
       fmt - simple optimal text formatter

SYNOPSIS
       fmt [-WIDTH] [OPTION]... [FILE]...

DESCRIPTION
       Reformat each paragraph in the FILE(s),
       writing to standard output.  The option
       -WIDTH is an abbreviated form of
       --width=DIGITS.

       With no FILE, or when FILE is -, read
       standard input.

7、pr - 按页格式化文本

pr 程序提供两种基本服务:首先, pr 将文本格式化成页;其次,pr 确保每页都有自己的标题、边缘和页号。(convert text files for printing)

但是,pr 程序不仅仅是将文本简单地分成页并生成标题、边缘和页号。pr 还可以将一个单独文件中的文本按列排序;还可以将多个文件中的文本合并在一起,每个文件进入自己的列。

语法:pr [OPTION]... [FILE]...

常用选项:

  • -h text,text 是标题中间的文字
  • -l n,n 是每页的行数
  • -o margin,(offset)偏移,margin 是左边缘的大小
  • -W width,width 是输出的宽度,默认是72字符
  • +beg [:end],beg 表示开始打印的页号,end 表示最后需要打印的页号。如+2:5表示只格式化并打印第2页至第5页。
  • -d,使用双倍行距文本
  • -t,移除标题
  • -columns,分列打印,columns 为一个数字,如-2表示把文本分成两列(即把原本两页的内容合并成一页中的两列内容,以此类推)
  • -m,(merge)合并。将多个文件分别格式化成单独的列。

例:

[nosee@instance-4 ~]$ man pr | fmt -uw 100 |nl -ba | pr +2 -h '---pr手册---' | head -n 20


2022-01-13 20:46                   ---pr手册---                   Page 2


    57	       -m, --merge
    58	              print all files in parallel, one in each column, truncate lines, but join lines
    59	              of full length with -J
    60	
    61	       -n[SEP[DIGITS]], --number-lines[=SEP[DIGITS]]
    62	              number lines, use DIGITS (5) digits, then SEP (TAB), default counting starts with
    63	              1st line of input file
    64	
    65	       -N, --first-line-number=NUMBER
    66	              start counting with NUMBER at 1st line of first page printed (see +FIRST_PAGE)
    67	
    68	       -o, --indent=MARGIN
    69	              offset each line with MARGIN (zero) spaces, do not affect -w or -W, MARGIN will
    70	              be added to PAGE_WIDTH
    71	

七、查找:grep、look

1、grep - 选取包含特定模式的行

grep 程序从标准输入或者文件中读取数据,抽取所有包含特定模式的行,并写到标准输出。(print lines that match patterns)

grep 中的 g 代表“global 全局”,re 代表“regular expression 正则表达式”,p 代表“print 打印”。

grep 的变体有:egrep, fgrep, rgrep。(这些变体已被弃用,提供这些变体是为了向后兼容)
In addition, the variant programs egrep, fgrep and rgrep are the same as grep -E, grep -F, and grep -r, respectively. These variants are deprecated, but are provided for backward compatibility.

语法:
grep [OPTION...] PATTERNS [FILE...]
grep [OPTION...] -e PATTERNS ... [FILE...]
grep [OPTION...] -f PATTERN_FILE ... [FILE...]

例:

[nosee@instance-4 ~]$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash

常用选项:

  • -c,(count)统计所抽取行的数量
  • -i,(ignore)忽略大小写
  • -n,在选取的数据行前面加上它在原本数据中对应的位置(行号)
  • -l,(list filename)不显示包含该模式的各行,而是将包含这种模式的文件名称写出来
  • -L,与 -l 选项正好相反,将不包含这种模式的文件名称写出来
  • -w,指定只希望搜索完整的单词
  • -v,(reverse 相反)选取不包含指定模式的行
  • -x,查找那些完全由搜索模式构成的行
  • -r,(recursive 递归)搜索整个目录树。(相当于rgrep)
  • -F,搜索固定的字符串,而不是正则表达式。(相当于fgrep)
  • -E,允许使用扩展正则表达式。(相当于egrep)
  • --color 搜索到的内容加上颜色显示

例:统计在 /etc 目录下,名字以 rc 开头的文件

[nosee@instance-4 ~]$ ls /etc/ | grep '^rc'
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rcS.d
[nosee@instance-4 ~]$ ls /etc/ | grep -c '^rc'
8

例:递归查找目录www下文件中包含'phpinfo'的文件,并显示所在位置

[nosee@instance-4 ~]$ grep -rn phpinfo www
www/hi.php:5://phpinfo();
www/phpinfo.php:4:phpinfo();

2、look - 选取特定模式开头的行(有序文本)

look 程序搜索以字母顺序排列的数据,并查找所有以特定模式开头的行。(display lines beginning with a given string)

语法:look [-bdf] [-t termchar] string [file ...]

常用选项:

  • -d,(dictionary 字典)只考虑字母和数字,忽略标点符号和其它特殊字符
  • -f,忽略大小写

例:

[nosee@instance-4 ~]$ look -f x look-test.txt
X11
xattr.conf
xdg

look 不能从标准输入中读取数据,它必须从一个或多个文件中获取输入。所以,严格地讲,look 并不是一个过滤器。
对于标准输入来说,程序每次只能读取一行数据。但是,look 程序是使用一种“二分查找”的搜索方法,要求同时访问所有的数据。基于这个原因,look 程序可以在管道线的开头使用,但不能在管道线中间或末尾使用。

look 有两大优点:易于使用并且速度非常快。

通过使用 look 程序搜索字典文件,还可以用于单词查找。
假设你想输入一个单词,但是不确定它的拼写,则可以使用 look 来做检查。如:simultaneous

[10:46 @nosee ~]$ look simult
simultaneous
simultaneously

使用man look说明可以查看字典文件存放在什么位置,感兴趣的话也可以使用wc -l命令去查看一下该字典文件上共收录了多少个单词:

[10:50 @nosee /usr/share/dict]$ cat american-english | wc -l
102401

八、排序、组合及变换:sort、uniq、join、tr、sed

1、sort - 排序数据

sort 程序用于排序数据以及查看数据是否已经有序。(sort lines of text files)

语法:sort [OPTION]... [FILE]...sort [OPTION]... --files0-from=F

sort 程序拥有极大的灵活性,它即可以比较整行,也可以从每行中选取部分(字段)进行比较。使用 sort 的最简单的方法就是排序一个单独的文件、比较整行并在屏幕上显示结果。(默认情况下是 ASCII 表的顺序进行排序)

常用选项:

  • -o filename,(output 输出)将排序好的数据存放到 filename 文件中。
  • -d,(dictionary 字典)只查看字母、数字和空白符(空格和制表符),忽略其它字符对排序的影响(如标点符号)
  • -f,(fold,等同)同等对待大写字母和小写字母,即忽略大小写。
  • -n,(numeric,数字)识别行开头或者字段开头的数字,并按照数字进行排序。
  • -r,(reverse,反向)按反向顺序对数据排序。
  • -u,(unique,唯一)相同的行只留下一行
  • -c,(check,检查)检查数据是否已经有序
  • -cu,表示检查数据是否已经有序,并且所有行都是唯一

例:

[nosee@instance-4 ~]$ sort -f sorttest.txt
batch-size=NMERGE
Characters in a field are counted from the beginning of the preceding
compress-program=PROG
debug
files0-from=F
in the field; both are origin 1, and the stop position defaults to the
line's end.  If neither -t nor -b is in effect,
r, --reverse
random-source=FILE
s, --stable

2、uniq - 查找重复行(有序文本)

uniq 程序用于查找有序数据中的重复行。(report or omit repeated lines)

语法:uniq [OPTION]... [INPUT [OUTPUT]]

uniq 程序可以执行4项不同的任务:消除重复行、选取重复行、选取唯一行、统计重复行的数量

常用选项:

  • -d,只查看重复行
  • -u,只查看非重复行
  • -c,统计每行重复的次数

例:删除重复行

[nosee@instance-4 ~]$ cat uuu.txt 
aaaaaa
dddddd
dddddd
ccc
fffff
fffff
gggg
hhhhh
[nosee@instance-4 ~]$ uniq uuu.txt 
aaaaaa
dddddd
ccc
fffff
gggg
hhhhh
[nosee@instance-4 ~]$ uniq -c uuu.txt 
      1 aaaaaa
      2 dddddd
      1 ccc
      2 fffff
      1 gggg
      1 hhhhh

3、join - 合并两个文件中的数据(有序文本)

join 程序基于特定字段的值将两个有序文件组合在一起。(join lines of two files on a common field)

语法:join [OPTION]... FILE1 FILE2

常用选项:

  • -a1,显示第一个文件的所有行
  • -a2,显示第二个文件的所有行
  • -v1,查看第一个文件中没有匹配的行
  • -v2,查看第二个文件中没有匹配的行
  • -i,(ignore)忽略大小写
  • -1 num,设置第一个文件的连接字段,默认为1
  • -2 num,设置第二个文件的连接字段,默认为1

注意:

  • 选项-a与选项-v不可以同时使用(如-a1 -v2);但是-a1 -a2这样是可以的,称之为外联接,反之在默认情况 join 程序为内联接。
  • 默认情况下,jion 假定各个字段之间用空白符分隔(空格或制表符)
  • 设置连接字段,如-1 3 -2 4表示用第一个文件的第三个字段和第二个文件的第四个字段进行连接。

例:

[nosee@instance-4 ~]$ cat aaa.txt 
111	gdfgseer
222	srgerge
333	serhger
444	jjjjj
[nosee@instance-4 ~]$ cat bbb.txt 
111	地胉
222	我人
333	哈哈
555	嘿嘿
[nosee@instance-4 ~]$ join  aaa.txt bbb.txt 
111 gdfgseer 地胉
222 srgerge 我人
333 serhger 哈哈
[nosee@instance-4 ~]$ join  -a1 aaa.txt bbb.txt 
111 gdfgseer 地胉
222 srgerge 我人
333 serhger 哈哈
444 jjjjj
[nosee@instance-4 ~]$ join  -v2 aaa.txt bbb.txt 
555 嘿嘿

4、tr - 改变或者删除指定的字符

tr(translate 转换)程序可以对字符执行3种不同的运算。(translate or delete characters)
1)可以将字符改变成其它字符。
2)可以指定如果要转换的字符连续出现不止一次,则用一个单独的字符替换。
3)可以删除指定的字符

语法:tr [OPTION]... SET1 [SET2]

常用选项:
-s,将SET1中的多个连续字符替换为一个单独的字符
-d,删除指定的字符,使用该选项时,参数SET2则不需要
-c,匹配所有不在SET1中的字符

常用参数

  • SET1,需要查找的字符组
  • SET2,用作替换的字符组

SET1SET2常用组合:

  • [:lower:],小写字母,相当于a-z
  • [:upper:],大写字母,相当于A-Z
  • [:digit:],数字,相当于0-9

例:

[nosee@instance-4 ~]$ cat ddd.txt 
root:x:0,0
sshd:x:105,65534
sync:x:4,65534
sys:x:3,3
uucp:x:10,10
www-data:x:33,33
[nosee@instance-4 ~]$ tr s S < ddd.txt 
root:x:0,0
SShd:x:105,65534
Sync:x:4,65534
SyS:x:3,3
uucp:x:10,10
www-data:x:33,33
[nosee@instance-4 ~]$ cat ddd.txt | tr ':,' \~
root~x~0~0
sshd~x~105~65534
sync~x~4~65534
sys~x~3~3
uucp~x~10~10
www-data~x~33~33
[nosee@instance-4 ~]$ cat ddd.txt | tr -s '0-9' '?'
root:x:?,?
sshd:x:?,?
sync:x:?,?
sys:x:?,?
uucp:x:?,?
www-data:x:?,?

当使用特殊字符时,记得要使用\来引用。

例:将小写字母替换为大写字母

[nosee@instance-4 ~]$ cat ddd.txt | tr a-z A-Z
ROOT:X:0,0
SSHD:X:105,65534
SYNC:X:4,65534
SYS:X:3,3
UUCP:X:10,10
WWW-DATA:X:33,33
[nosee@instance-4 ~]$ cat ddd.txt | tr [:lower:] [:upper:]
ROOT:X:0,0
SSHD:X:105,65534
SYNC:X:4,65534
SYS:X:3,3
UUCP:X:10,10
WWW-DATA:X:33,33

转换不可见字符:

代码 控制键 八进制码 名称
\b ^H \010 退格
\t ^I \011 制表符
\n ^J \012 新行/换行
\r ^M \015 回车
\ 反斜线
当 tr 程序需要使用以上字符时,需要使用以上的代码或八进制码。如:
[nosee@instance-4 ~]$ cat ddd.txt | tr ':,' '\t'
root	x	0	0
sshd	x	105	65534
sync	x	4	65534
sys	x	3	3
uucp	x	10	10
www-data	x	33	33

例:将多个空格替换为一个空格(挤压空格)

tr -s ' ' ' ' < filename

5、sed - 非交互文本编辑

文本编辑器就是一个允许对文本执行操作的程序,一般情况下,可以进行插入、删除、改变、搜索等操作。比较流行的 vim 与 emacs 这类是属于交互式文本编辑器,而 sed 则属于非交互式文本编辑器。

sed(stream editor 流编辑器)需要提前设计命令,然后将命令发送给程序,程序再自动地执行命令。(stream editor for filtering and transforming text)

sed 可以从文件中读取数据,也可以从标准输入中读取数据。

语法:sed [OPTION]... {script-only-if-no-other-script} [input-file]...

常用选项:

  • -i,(in-place 原地)将输出保存到一个临时文件,一但所有数据都成功处理完,就将临时文件复制到原始文件。
    使用-i选项时应特别小心,因为它会改变原文件。一般先运行一个没有-i选项的命令查看,检查没问题后再加上-i更为稳妥。
  • -e,执行多条命令
  • -E-r,允许使用扩展正则表达式

{script-only-if-no-other-script}】的语法:

  • s/search/replacement/[g],这是最常用的搜索替换模式,search为正则表达式,replacement是替换文本。默认情况只改变每行第一个匹配到的字符串,加上g则表示全文搜索替换
  • s/search//[g],该模式中,原本replacement的内容没有了。意思就是,删除所匹配到的内容。
  • [/address|pattern/]s/search/replacement/[g],在指定的区域搜索,address表示一个或者多个行的地址,pattern是一个字符串。
    如:5s/search/replacement/[g]表示只对第5行执行搜索替换,5,$s/search/replacement/[g]表示第5到最后一行。
    /ok/s/search/replacement/[g]表示包含ok的行,/[0-9][0-9]/s/search/replacement/[g]表示包含有两个连续数字的行。

例:

[nosee@instance-4 ~]$ cat ddd.txt 
root:x:0,0
sshd:x:105,65534
sync:x:4,65534
sys:x:3,3
uucp:x:10,10
www-data:x:33,33
[nosee@instance-4 ~]$ sed 's/r[a-zA-Z]*t/***/g' ddd.txt 
***:x:0,0
sshd:x:105,65534
sync:x:4,65534
sys:x:3,3
uucp:x:10,10
www-data:x:33,33

例:执行多条命令

[nosee@instance-4 ~]$ cal
    January 2022      
Su Mo Tu We Th Fr Sa  
                   1  
 2  3  4  5  6  7  8  
 9 10 11 12 13 14 15  
16 17 18 19 20 21 22  
23 24 25 26 27 28 29  
30 31                 
[nosee@instance-4 ~]$ cal | sed \
> -e 's/Su/一/g' \
> -e 's/Mo/二/g' 
    January 2022      
一 二 Tu We Th Fr Sa  
                   1  
 2  3  4  5  6  7  8  
 9 10 11 12 13 14 15  
16 17 18 19 20 21 22  
23 24 25 26 27 28 29  
30 31   

例:使用扩展正则表达式,修改日期函数显示日期时的间隔

[nosee@instance-4 ~]$ cal
    January 2022      
Su Mo Tu We Th Fr Sa  
                   1  
 2  3  4  5  6  7  8  
 9 10 11 12 13 14 15  
16 17 18 19 20 21 22  
23 24 25 26 27 28 29  
30 31                 
[nosee@instance-4 ~]$ cal | sed -E \
> -e 's/[ ]{7,}/\t\t\t\t\t\t/g' \
> -e 's/[ ]{4,}/\t\t/g' \
> -e 's/[ ]*$/-/g' \
> -e 's/[ ]{2}/ 0/g' \
> -e 's/^[ ]{1}/0/g' \
> -e '2,$s/[ ]{1}/\t/g' \
> -e 's/1-/ 1/g' \
> -e '1s/[ ]{1}/       /g' \
> -e 's/\<[0]/ /g' \
> -e 's/-//g'
		January       2022		
Su	Mo	Tu	We	Th	Fr	Sa
						 1
 2	 3	 4	 5	 6	 7	 8
 9	10	11	12	13	14	15
16	17	18	19	20	21	22
23	24	25	26	27	28	29
30	31	

九、分页程序:less、more

虽然 less、more 不是过滤器,但是经常在管道命令的最后会使用它们来显示文本,特别是 less ,所以也需要好好了解一下。

1、less

less 程序工作在原始模式中,因此它能够完全接管命令行和屏幕,根据自己的需要显示行及处理字符。

基本指令 说明
hH 显示帮助信息
q:qQ:QZZ 退出
g 跳到第一行
G 跳到最后一行
= 显示当前行号和文件名
<Space><PgDn>f^F^V 前进一屏
<PgUp>b^BESC-v 后退一屏
d^D 前进半屏
u^U 后退半屏
<Return>e^Ej^N 前进一行
n<Return>n↓ 前进 n 行
y^Yk^K^P 后退一行
nyn↑ 后退 n 行
ng 跳到第 n 行
np 跳到文本的 n% 处
/pattern 向前搜索指定模式(可以是简单字符串或正则表达式)
高亮显示出所有匹配的结果,下同
?pattern 向后搜索指定模式(可以是简单字符串或正则表达式)
n 重复搜索:相同方向
N 重复搜索:相反方向
!command 执行指定的 shell 命令
v 使用当前文件启动 vi 编辑器
-option 改变指定的选项 option(如:-i忽略大小写,-m显示百分比)
_option 显示指定的选项 option

只需要记住一些自己常用的指令就行。

处理多文件指令 说明
:n 切换到列表中的下一个文件
:p 切换到列表中的前一个文件
:x 切换到列表中的第一个文件
e 在列表中插入一个新文件
:d 从列表中删除(移出)当前文件
:f 显示当前文件的名称,同“=
/*pattern 向前搜索指定模式 (将整个文件的列表视为一个大文件)
?*pattern 向后搜索指定模式 (将整个文件的列表视为一个大文件)

同时 less 还有大量的选项可供使用。

常用选项:

  • -s,(squeeze,挤压)将多个空白行替换为一个空白行
  • -m,显示百分比
  • -M,显示更多信息:文件名、行号、百分比
  • -e or -E,当文件显示结束后,自动退出
  • -N,显示行号
  • -i,在搜索模式中忽略大小写

+(加号)选项允许指定 less 程序从什么地方开始显示数据。(也就是基本指令表大部分显示指定数据的命令都可以用)

例:浏览文件 fillename.txt,显示当前位置的百分比,并从匹配到'name'字符串的位置开始查看。

less -m +/name fillename.txt

例:从50%的位置开始查看数据

less +50p fillename.txt

2、more

向前分页浏览文件内容。more 可以认为是一个简化版的 less ,所以也不过多介绍了。

基本指令 说明
h 显示帮助信息
qQ 退出
= 显示当前行号
<Space>f 前进一屏
b^B 后退一屏 (在管道命令中该指令无效)
d^D 前进半屏
<Return> 前进一行
/pattern 向前搜索指定模式
/ 重复上一次搜索
!command 执行指定的 shell 命令
v 使用当前文件启动 vi 编辑器

十、参考

书箱:《Unix & Linux 大学教程》第16-19章 (美)Harley Hahn 著 张杰良 译

posted @ 2022-01-25 12:54  四月不见  阅读(203)  评论(0编辑  收藏  举报