管道线中一个个的命令就是过滤器(从标准输入中接受数据,然后再传到标准输出中),但是在最前面的和在最后面的不一定是过滤器。

基础

cat 复制

cat的用途就是把标准输入中的数据复制到标准输出中

应用:可以与重定向结合。cat > data,这样从键盘中输入的数据将直接传到data文件中

此外还可以让文件内容显示在控制台上,有 cat < data,标准输入变成了data文件,标准输出是屏幕。为了方便,直接cat 文件名也是可以的

此外,tail也有类似的功能,但是它只能显示最后的十行

另外一个应用就是把一个文件复制到另一个文件。例如,cat < data > newdata

增强cat功能

cat < file…= cat file …

有三个点说明了可以同时输入多个文件,这样就为组合多个文件提供了途径

cat data1 data2 data3 >file

后缀:

 -n 在每行后面加一个行号
 -b 与-n一起使用,不要对空白行加行号
 -s 将多个连续的空白行变成一个空白行

split 分为不同文件

语法 split [-d] [-a num] [-l lines] [file [prefix]]

作用: 将一个大文件分解成几个小文件。默认情况下,split将创建1000行长的空间

参数:

-l 创建一个5000行的空间
-d 将文件名改为从00开始编号
-a 后面加数字,例如3表示从000开始,总共1000个文件名

默认情况下,split创建的文件将以x开头,后面加aa,ab等

tac 反转复制

相关过滤器: cat,rev

作用:和cat类似,但是在写入文件时把文件内容反转(tac是将cat反过来)。注意,这里的反过来并不是指从后往前倒着写,而是把行与行将顺序反过来。

rev 反转字符顺序

相关过滤器: cat tac

作用: 将各行字符顺序反转

语法: rev [file…]

例如: 有一个文件data,里面有

12345
abcde
AxAxA

之后用rev后会变成

54321
edcba
AxAxA

rev也是直接输出到标准输出上的,也就是说并不会对源文件造成改变,如果想输出到文件中,还要重定向一下

head,tail 从数据开头或者结尾读取

语法: head/tail [-n lines],lines是希望选择的数据行

默认情况下,head和tail都只会选择十行数据,用-n可以选择任意行数

例: calculate | tail -n 15

colrm 删除数据列

相关过滤器: cut paste

colrm(“column remove”)程序从标准输入中读取数据,删除指定数据列(也就是竖的删除),将剩余数据写入标准输出

语法: colrm [startcol [endcol]],编号从1开始

例: colrm 14 30 <students | less

比较文件

cmp 比较两个任意文件

相关过滤器:comm diff sdiff

语法: cmp file1 file2

cmp程序逐字节的比较文件,查看两个文件是否相同。如果两个文件相同,那么不做任何处理,如果不同,将会返回第一个不同的行和列

comm 比较有序文件

语法:comm [-123] file1 file2

comm程序一行一行的比较两个有序的文本间,程序输出三列,第一列输出只包含在第一个文件中的行,第二列输出只包含在第二个文件中的行,第三列输出两个文件中都有的行。

因为comm是逐行比较,所以在比较之前最好使用sort进行排序

参数: -1 -2 -3 取消第一二三列的输出

diff 比较无序文件

语法: diff [-bBiqswy] [-c| -Clines | -u | -Ulines] file1 file2

lines是说明上下文关系的行号

输出: diff的输出有三个不同的单字符指示: c(change) d(delete) a(append)。这三个字符说明了要想让两个文件相同需要做哪些改变。

这三个字符左右两边都会有数字,代表着需要修改的行号。例如,3c3代表把左边文件中的第三行变成右边文件中的第三行。

diff要求改变时,就会给出每一个文件的实际行,第一个文件中的行用小于号标记,第二个文件中的行用大于号标记。两组行之间还会有横线分隔开

例如,第一个文件为

abcd
asdf
as df
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

第二个文件为
a     
abcd
asdf
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

结果为
0a1
> a
3,4c4
< as df
< xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
---
> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

a左边的数代表在左边数后面追加一行,例如0a1代表在第0行后面加上右边的第一行

d一般只需要管左边的数字,它的意思是删去左边的那一行

c表示3,4行和第三行有不同,分隔符上面是第一个文件,下面是第二个文件

参数:

-i 忽略大小写区别
-w(whitespace) 忽略所有空白符
-b 忽略空白符数量上的区别,就是把多个空白符看成一个
-B 忽略所有空白行,
-q 当两个文本不同时,忽略所有细节,只说两文本不同
-s 会明确告诉两个文本相同
-c 全文比较,+代表要增加,-代表要减少,!代表要替换
-u 与-c类似,但是把两个文件混合在一起显示,两个重复行只输出一个
-y 把两个文件并排输出

sdiff

语法: sdiff [-bBilsW] [-w columns] file1 file2

作用:与 diff -y 类似,并排比较
参数:

-l 当两个文件有共同行时,只显示左边的列
-s 不显示两个文件中任何相同的行
-w+数字 改变列的宽度
-i 忽略大写和小写的区别
-W 忽略所有的空白符
-b 忽略空白符数量上的区别
-B 忽略所有空白行

差分

例如: diff game1_ver1.0.c game2_ver2.0.c > game2_ver2.1

这个命令会把第一个文件和第二个文佳之间的差保存下来,这样可以节省空间,此外在日后不慎丢失文件时也有办法快速找回

cut 抽取数据列

相关过滤器: colrm join paste

语法: cut -c list [file…]

list就是要抽取的数据列,各个列之间用逗号隔开,不能有空格,或者14-19表示从14列到19列

作用:抽取指定的列

这种按列切分遇到长度不同的数据时就显得无能为力,因此还有另一种抽取方式,抽取字段,即按照一定的定界符进行分割(如逗号,空格等)

参数:

-c  list [file...] list表明抽取第几个字段
-f list [-d delimiter] [-s] [file...] -d后面是定界符种类 -s(suppress 抑制)抛弃没有定界符的行。例如 cut -f 1 -d ':' ./temp

paste

语法: paste [-d char…] [file…]

其中char是用来做分隔符的字符,默认情况为一个制表符或者是空格

作用: 把几个文件组合成一个表格(组合数据列)

如果指定了不止一个定界符,那么将会轮流使用定界符

例如: paste -d ‘|%’ name phone ,这个指令中就有两个定界符

统计和格式化

nl 创建行号

语法: nl [-v start] [-i increment] [-b a] [-n ln|rn|rz] [file…]

start是起始行号 ,increment是增量

作用:希望在一些数据中永久的插入行号,在输出中临时插入行号。一般状况下,插入的行号都是临时的,原始数据并不会发生改变,除非重定向输出到文件中。

默认情况下,不会对空行编号

参数:

-v 改变起始编号,默认起始编号是1
-i 改变增量,默认增量为1
-b a 对所有行编号,包括空行
-n ln 左对齐 rn 右对齐 rz 右对齐,有前导0

wc(word count)统计行单词和字符的数量

语法: wc [-clLw] [file…]

作用:统计行,单词,字符的数量。所统计的数据可以来自另一个程序或者是一个或多个文件

输出依次输出行,单词数,字符数 和文件名。如果不止一个文件,那么会为每一个文件显示一个输出,然后最后一行是一个总输出。

参数

-l 统计行
-w 统计单词
-c 统计字符
-L 该选项显示输入中最长行的长度

此外,还可以用wc来统计某一目录中文件的数量,假设一个文件一行,用ls file | wc -l.

制表符和空格

在老式机器中,会在某些特定的为做一些机器标记,这些标记叫做制表位,如果按了制表位,那么机器会直接跳转到下一个制表位上,tab键与这个作用类似。一旦按了tab键,那么他将会自动跳转到下一个制表位。例如输入A<Tab>BBBB<Tab>CCC,实际上看起来中间有空格,实际上只有一个Tab

可视化制表符

第一种办法是在vi中,set list 那么制表符会转化成^I符号

expand 将制表符转化成空格

语法: expand [-i] [-t size] [-t list] [file…]

其中size是固定宽度制表符的大小(默认为8),list是制表位列表

作用:expand将输入文件中所有的制表符转化成空格,别切维持与原文本相同的对齐方式

-i 只转换开头的制表符,其他的制表符保持不变

unexpand 将空格转化成制表符

语法: unexpand [-a] [-t size] [-t list] [file…]

其中size是制表符的大小(希望设置的),list是制表位列表

一般情况下,unexpand只转化第一行的空格,如果想要转换所有行的空格,那么需要-a选项

fold 格式化行

相关过滤器: fmt ,pr

语法: fold [-s] [w witch] [file…]

其中witch是新行的宽度。

作用: 将长的行分割成短行。也就是把一行分成多行。其实就是在适当位置插入一个回车符

默认状态下,80个字符为一行。

-s选项是告诉程序不要分割单词,也就是说如果那个单词正好在要分割的位置,那么现在会先显示这个单词在转到下一行。

fmt 格式化段落

语法: fmt [-su] [-w width] [file…]

作用:让各行连接在一起,并且不改变空白符。

当它读取文本时,假定段落由空行分隔。一个“段落”就是一个或多个连续的文本行,不包括空行。fmt根据下列规则读取一个段落

  • 行宽: 让每行尽可能的长,并且不超过指定的长度。默认情况下,每行最多75个字符
  • 句子: 无论何时,尽可能在句子末尾分隔行。避免在句子的第一个单词之后或最后一个单词之前分隔行。
  • 空白符: 保持单词及空行之间的所有缩进,空格。
  • 制表符: 所有制表符转化成空格。并在最后输出时合适的位置插入制表符

说起来复杂,其实就是让那些长短不一的段落尽量变得长。

例如

As we all know,
success cones slowly and
is due to a number of different factors all coming
together
over a period of years

使用命令后
As we all know, real success comes slowly and is
due to a number of different factors all coming
together over a period of years.

此外,它是一段的作用,如果两行之间有个空行就把他们当成两段单独处理,互不影响

参数

-u(uniform spacing 统一间距) 减少空格,每个单词之间最多只有一个空格,句子末尾最多只有两个空格。
-w 设定宽度

pr 按页格式化文本

语法: pr [-dt] [+beg[:end]] [-h text] [-l n] [-o margin] [-W width] [file…]

作用: 按页格式化文件,以便于打印。

其中 beg是需要格式化的第一页,end是最后一页,text是标题,n是每页的行数,margin是左边缘的大小,width是输出的宽度。

默认情况下,pr是通过顶端插入一个标题,左边插入一个边缘,底部插入一个页尾来格式化文件。标题包括修改时间,文件名称和页号。

如果想查看效果,最好在less程序中

参数:

-d 双倍行距文本(word中的)
+begin;end 从那页到哪页格式化
-l 改变每页总行数
-o 设置左边缘
-W 改变每一行的字符数(默认是72)

还可以按列格式化文本

语法: pr [-mt] [-columns] [-l lines] [-W width] [file…]

column是输出列的数量,lines是每页的行数,width是每行的字符数。这个选项不建议用,会截断字符。

选取,排序,组合,变换

grep 选取特定模式的行

相关过滤器: look strings

语法: grep [-cilLnrsvwx] pattern [file…]

pattern是要搜索的格式

作用: 从标准输入或文件中读取数据,抽取所有包含特定模式的行,并写入标准输出。

这个模式可以是字符串标点符号等,但是如果是标号或者特殊字符时,最好用’’强引用,以防止歧义。

选项:

-c(count) 统计所抽取行的数量,但不显示行本身
-i(ignore) 忽略大小写的区别
-n 所选行在原文件中的位置
-l(list),如果在不只一个文件中搜索,使用这个选项可以只把匹配的文件名列举出来,此时文件名也要输出多个
-L 显示不包含该模式的文件名
-v(reverse) 选取不包含模式的行
-x 选取完全匹配的行
-r(recursive递归) 搜索整个目录树

fgrep,egrep grep变体

fgrep,历史上使用,现在基本不用

egrep grep扩展版本,功能比grep强大,可以通过 grep -E的方式
-w 只匹配完整的单词,并且最好配合-l使用。

look 选取以特定模式开头的行

格式: look [-df] pattern file…

作用: 搜索以字母顺序排列的数据,并查找所有以特定模式开头的行。然后输出这些行

look其实并不是一个过滤器,它只能从文件中读入,因此只能写于管道线的开头

-d 忽略标点和其他字符,本来是指搜索第一个单词

-f(fold同等) 忽略大写和小写的区别

sort 排序

格式 sort [-dfnru] [-o outfile] [infile…]

作用: 排序数据和查看数据是否已经有序。他可以比较整行,也可以从每行中选取一部分进行比较。

sort可以重定向输出到另一个文件,但是不能输出到输入文件

例如: sort temp > temp 是不可以的

但是可以使用-o选项,此时该文件中原有数据将会被保存,排序后的数据也会被追加到这个文件中

-dfnr 控制数据排序的顺序

-d(dictionary) 只查看字母,数字和空白符,当确定有阻碍排序的因素(如标点符号等),可以使用这个选项。

-f(fold 等同)不区分大小写

-n(numeric 数字) 识别开头或者字段开头的数字,并按照数字进行排序

-r 反向排序

-u(unique 唯一) 对于相同行,只保留一行

检测数据是否有序 -c

-c(check) 不会排列数据,只会告诉数据是否有序,如果有序,将不会显示任何内容

uniq 查找重复的行

语法: uniq [-cdu] [infile [outfile]

作用: 消除重复行,选取重复行,选取唯一行,统计重复行的数量。不加选项输出非重复行和只输出一次重复行

注意uniq的输入必须是有序的

-d 只查看重复行

-u 只查看非重复行

-c 统计重复行出现的次数

join 合并两个文件的有序数据

相关过滤器: colrm cut paste

语法: join [-i] [-al|-vl] [-a2|-v2] [-l field1] [-2 field2] file1 file2

其中field是引用特定数段的数字

作用: 把两个文件中对应行合并到一起。但是这又和sort不同,sort是直接把两个文件拼接在一起,而join则是重复数据合并为一个输出。不重复数据直接输出。读取输入时,会忽略前导空白符。

不使用其他标号情况下,只会显示有匹配的连接字段(也就是两个文件对应行有相同字段),如果使用-a(all)选项,将会显示整个文件,后面要加a1或a2。a1代表把第一个文件中不匹配的内容也加上去。如果是v1,显示V1中不匹配的行

-1+sum 将第一个文件中的第sum个字段和第二个文件中的第一个字段进行匹配

tsort 由偏序创建全序

语法: tsort file

作用:将一系列的事一件一件从头到尾输出

例如:两个单词第二个单词代表在第一个单词后要做的事

eat clean-dishes
clean-dishes watch-TV
shop cook
cook eat

在使用了tsort后,输出为
shop
cook
eat
clean-dishes
watch-TV

strings 在二进制文件中搜索字符串

语法: strings [-length] file…

在现代软件中基本都有这种功能,不再展开

转换字符 tr

语法: tr [-cds] [set1 [set2]]

set1是字符组

作用:可以将一个字符转化成另一个字符,例如将小写转化成大写,将制表符转化成空格,或者将0转化成x等。此外,还可以将多个字符变成一个字符,例如将多个空格转化成一个空格。最后,还可以删除指定字符,例如删除制表符。

例如: tr a A < old tr a-z A-Z < old

当需要替换的字符中出现由特殊意义的字符时,需要引用他们

还有几种特殊的缩写 [:lower:] 代表小写字母,[:upper:]代表大写字母,[:digit:]代表数字

tr还可以转换不可见字符

例如: tr ‘\n’ ‘\t’ < old

参数:

-s 多个字符变成一个字符 例如 tr -s ' ' ' ' < old
-d 删除指定字符
-c 把没选上的字符变成另一个字符,例如 tr -c ' \n' x < old,这个的意思就是除了空格和换行之外其他所有字符都变成x

sed 非交互式文本编辑

交互式文本编辑就是有一个窗口,例如gedit vi等。而非交互式则需要提前设计命令,然后将命令发给程序。

语法: sed [-i] command | -e command… [file…]

command是sed命令

作用: sed是一个标准的过滤器,可以对标准输入或者标准输出进行修改

sed从输入流中每次读取一行。然后执行下面三个步骤

  1. 从输入流中读取一行
  2. 执行指定的命令,对该行进行必要的修改
  3. 将该行写入输出流中

因为是修改标准输入或者标准输出,所以源文件不会被修改,如果要修改原文件,可以加上-i(in-place)选项,这个选项会将输出保存到一个临时文件,一但所有数据处理完,sed就会把临时文件复制到原文件中

使用sed进行替换

想要用sed对标准输入或输出的内容进行修改,可以采用 s命令

形式: /address|pattern/ s /search/replacement/[g]

address 是输入流中一个行或者多个行的地址,pattern是一个字符串,search是正则表达式,replacement是一个替换文本

例如 sed s/harley/Harley,这个例子意思就是把每一行的第一个harley改成Harley,如果想把所有都改了,那么在后面要加上一个g

如果只对一些行进行操作,可以用下列语法:

number[,number] /regex/

number是行号

例如: sed ‘5s/harley/Harley/g’ names