1.管线命令(pipe)
学习正规表示法之前,让我们先了解一下管线命令(pipe)。
1.1 获取命令:cut、grep
cut
功能简介:
[~]$ cut -d "分割字符" -f fields
[~]$ cut -c 字符区间
选项与参数:
-d :后面加分割字符。与-f一起只用;
-f :依据-d的分割字符将一段讯息分区为数段,用-f是取出第几段的意思;
-c :以字符的单位取出固定字符区间;
示例1:将PATH变量取出,找出第3个路径
[~]$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/usr/local/mysql/bin
[~]$ echo $PATH | cut -d ":" -f 3 ##如果取多个路径用","分割
示例2:将export输出的讯息,取得第12字符以后的所有字符串
[~]$ export | cut -c 12-
示例3:用last将显示的登入者的信息,仅留下用户名
[~]$ last | cut -d ' ' -f 1
grep
cut是将一行讯息取出某部分我们想要的,而grep则是分析一行讯息,若当中有我们需要的,就将该行取出来。
功能简介:
[~]$ grep [-acinv] [--color=auto] '字符串' filename
选项与参数:
-a :将binary文件以text文件的方式搜索数据;
-c :计算找到"字符串"的次数;
-i :忽略大小写;
-n :顺便输出行号;
-v :反向选择,即显示出没有"字符串"内容的那一行;
--color=auto :可以将找到的关键词部分加上颜色显示;
示例1:将last中,有出现root的行取出来;
[~]$ last |grep 'root'
示例2:与示例1相反,只要没有root的就取出;
[~]$ last |grep -v 'root'
示例3:在last中,只要有root就取出且仅取出第一行;
[~]$ last |grep 'root' |cut -d ' ' -f 1
示例4:取出/etc/man_db.conf内包涵MANPATH的那几行;
[~]$ grep --color=auto 'MANPATH' /etc/man.conf
1.2 排序指令:sort、wc、uniq
sort
如果想对数据排序怎么做呢?
功能简介:
[~]$ sort [-fbMnrtuk] [file or stdin]
选项与参数:
-f :忽略大小写;
-b :忽略最前面的空格符部分;
-M :以月份的名字来排序,例如JAN、DEC等;
-n :使用纯数字进行排序,默认是以文字形态来排序的;
-r :反向排序;
-u :就是uniq,相同的数据,仅出现一行代表;
-t :分隔符,默认是用[tab]键来分隔的;
-k :以那个区间来进行排序;
示例1:将/etc/passwd中个人账号排序
[~]$ cat /etc/passwd | sort
示例2:/etc/passwd内容是以:来分隔的,想以第三栏来排序
[~]$ cat /etc/passwd | sort -t ':' -k 3 nobody [-n 让它使用数字排序]
示例3:last中,输出的数据仅取账号,并加以排序
[~]$ last | cut -d ' ' -f 1 |sort
uniq
如果想去重怎么做?
功能简介:
[~]$ uniq [-ic]
选项参数:
-i :忽略大小写字符的不同;
-c :进行计数;
示例1:使用last将账号列出,仅取出账号列,进行排序后去重;
[~]$ last | cut -d ' ' -f 1 |sort |uniq
示例2:接上例,如果还想知道每个人的登入次数呢?
[~]$ last | cut -d ' ' -f 1 |sort |uniq -c
wc
如果我想知道/etc/passwd/man_db.conf文件有多少字,多少行怎么做?
功能简介:
[~]$ wc [-lwm]
选项与参数:
-l :仅列出行;
-w :仅列出多少字(英文单字);
-m :多少字符;
示例1:/etc/man_db.conf里面有多少相关字、行、字符数?
[~]$ cat /etc/man_db.conf | wc
140 720 4574 ##输出的分别代表:行、字数、字符数
示例2:last可以输出登入者,但是last最后两行并非账号内容,该如何以一行指令串取出登入系统的总人数?
[~]$ last | grep [a-zA-Z] | grep -v 'wtmp' | grep -v 'reboot' |grep -v 'unkown' |grep -v 'shutdown'|wc -l
1.3 双向重导向:tee
">" 标记会将数据流整个传送给文件或装置,因此我们必须去读取这个文件或装置。如果想要从这个数据流处理过程中获取某段数据该怎么做?
tee会同时将数据流分送到文件和屏幕,输出到屏幕的我们叫它"stdout"。
功能简介:
[~]$ tee [-a] file
选项与参数:
-a :以累加的方式,将数据加入file中。
示例1:将last的输出存到last.list中
[~]$ last | tee last.list
示例2:将ls的数据保存一份到ls.txt中,同时屏幕也有输出信息。
[~]$ ls -l | tee ls.txt |more
1.4 字符转换命令:tr、col、join、paste、expand
tr
tr可以删除一段数据中的文字,或者进行文字的替换
功能简介:
[~]$ tr [-ds] SET1 ...
选项与参数:
-d :删除数据中SET1的这个字符串;
-s :去重;
示例1:将last输出的数据,所有的小写编程大写;
[~]$ last |tr '[a-z]' '[A-Z]'
示例2:将/etc/passwd输出的数据,将冒号去掉;
[~]$ cat /etc/passwd | tr -d ':'
col
功能简介:
[~]$ col [-xb]
选项与参数:
-x :将tab键转换成对等的空格键
示例1:利用cat -A显示所有的特殊按键,以col将tab键转成空格键
[~]$ cat /etc/man.conf |col -x |cat -A
join
它表示处理两个文件之间的数据,主要在处理"两个文件中,有相同数据的那一行,才将它加在一起"。
功能简介:
[~]$ join [-til2] file1 file2
选项与参数:
-t :join默认以空格符分隔数据,并且比对第一个字段的数据,如果两个文件相同,则将两笔数据连成一行,且第一个字段放在第一个;
-i :忽略大小写;
-1:后面加数字,代表第一个文件要用第几个字段来分析;
-2:后面加数字,代表第二个文件要用第几个字段来分析;
示例1:将/etc/passwd与/etc/shadow相关数据整合成一栏
[~]$ head -n 3 /etc/passwd /etc/shadow ##可以看到这两个文件的最左边字段是相同的账号,并且以 :分割
[~]$ join -t ':' /etc/passwd /etc/shadow | head -n 3 ##相同的部分被移动到最前面了
示例2:/etc/passwd第四个字段是GID,/etc/group第三个字段是GID,怎么样整合?
[~]$ head -n 3 /etc/passwd /etc/group ## 他们中的第四个和第三个"0"则表示GID
[~]$ join - t ':' -1 4 /etc/passwd -2 3 /etc/group | head -n 3 ##相同的字段部分被移动到最前面了
注意:在使用join之前,你需要处理的文件应该要事先经过排序(sort)处理。否则,有些比对的会被略过。
paste
paste:"将两行贴在一起,中间以tab键隔开"。
功能简介:
[~]$ paste [-d] file1 file2
选项与参数:
-d :后面接分割字符,预设是以tab键来分割;
- :如果file部分写成 - ,表示来自stdin的意思;
示例1:将/etc/passwd与/etc/shadow同一行贴在一起
[~]$ paste /etc/passwd /etc/shadow
示例2:先将/etc/group读出,然后与示例1贴在一起,仅取出前三行
[~]$ cat /etc/group | paste /etc/passwd /etc/shadow - | head -n 3 ##这个例子重点在 - 的使用,表示stdin
expand
expand:将tab键转成空格键。
功能简介:
[~]$ expand [-t] file
选项与参数:
-t :后面加数字。定义一个tab键代表多少个空格键。
示例1:将/etc/man_db.conf行首是MANPATH的行就取出,仅取前三行;
[~]$ grep '^MANPATH' /etc/man_db.conf |head -n 3 ##行首的标志为^
示例2:接示例1,如果想要将所有的符号都取出来?
[~]$ grep 'MANPATH' /etc/man.conf |head -n 3 |cat -A ##cat -A 可以把所有的tab键显示为^I
示例3:接示例2,怎样将tab键设定代表为6个空格字符?
[~]$ grep 'MANPATH' /etc/man.conf |head -n 3 |expand -t 6 |cat -A ##expand将tab转成空格,所以cat -A查看不到了
1.5 分区命令:split
split:可以将一个大文件依据文件大小或行数来分区,就可以将大文件分区为小文件了。
功能简介:
[~]$ split [-bl] file PREFIX
选项与参数:
-b :后面加想分区成的文件大小,可以加单位,例如b,k,m等;
-l :以行数来进行分区
PREFIX :代表前导符,可作文分区文件的前导文字
示例1: /etc/services 有600kb,怎么分成300kb一个文件?
[~]$ split -b 300k /etc/services services
[~]$ ll -k services* ##可以看到被分成了servicesaa,servicesab,servicesac,services就是前导向名字了。
示例2:如何将上面3个小文件合成一个文件,档名为servicesback?
[~]$ cat services* >> servicesback
示例3:将ls -al / 输出的信息,每十行记录成一个文件;
[~]$ ls -al / | split -l 10 - lsroot ## 重点是 - ,它表示stdout或stdin。
1.6 参数替换: xargs
xargs : x是加减乘除的乘号,就是在产生某个指令的参数的意思。
功能简介:
[~]$ xargs [0epn] command
选项与参数:
-0 :如果输入的stdin含有特殊字符,例如`,\,空格键等,-0可以将它还原成一般字符。
-e :这个是EOF(end of file)的意思。后面加一个字符串,和字符串中间不没有空格键的,当xargs分析到这个字符串时会停止继续工作。
-p :在执行每个指令的argument时,都会询问使用者。
-n :后面加次数,每次command指令执行时,指定要使用几个参数。
示例1:将/etc/passwd内的第一列取出,仅取三行,使用id将每个账号内容显示出来
[~]$ id root ## 这个id可以查询用户的UID/GID等
[~]$ id $(cut -d ':' -f 1 /etc/passwd | head -n 3) ## $(cmd)可以预先取得参数,但id只能接受一个参数,上述指令会执行错误
[~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | id ## id并不是管道命令,此命令执行后,只会执行id
[~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs id ##依旧是错误,因为xargs一口气将全部的数据都给id处理,但是id只能接受1个参数。
[~]$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id
1.7 减号的用途
在管道命令中,尝尝会使用到前一个指令的stdout作为这次的stdin,例如下面的例子:
[~]$ tar -cvf - /home | tar -xvf - -C /tmp/homeback ## 将/home里面的文件打包,但打包的数据不记录到文件而是传送到stdout,经过管道后,传送给后面的 - 。
2.正规表示法
2.1什么是正规表示法?
简单来说,正规表示法就是处理字符串的方法,他是以行为单位进行字符串处理的行为,正规表示法通过一些特殊符号的辅助,可以让使用者对某些特定字符串进行搜索、删除、取代的处理。
它有基础正规表示法和延伸表示法。延伸表示法就是除了一些简单的操作,还可以以群组的字符串处理。例如:对Wechat和QQ字符串的搜索,注意是OR的关系而不是AND的关系。
2.2 基础正规表示法
正规表示法是处理字符串的一种表示方式,那么对字符排序有影响的语系就会对正规表示法的结果产生影响了。
语系对正规表示法的影响
为什么语系会影响正规表示法的输出结果?因为不同语系的编码数据是不同的,例如下面的例子:
LANG=C :0 1 2 ... A B C ... a b c ...
LANG=zh_TW :0 1 2 ... a A b ... z Z
所以使用正规表示法时,需要特别留意当时环境的语系,否则可能会发现与别人不同的搜索结果。
下面的练习使用"LANG=C"这个语系。 为了避免这个编码造成的英文与数字的获取问题,有些特殊符号我们也应该了解一下:
[:alnum:] :表示英文大小写字符及数字,即0-9,A-Z,a-z;
[:alpha:] :表示任何英文大小写字符,即A-Z,a-z;
[:blank:] :表示空格键和[tab]按键;
[:cntrl:] :表示键盘上的控制按键,即CR、LF、Tab、Del等等;
[:digit:] :表示数字0-9;
[:graph:] :表示除了空格键与[Tab]外的其他所有按键;
[:lower:] :表示小写字符,即a-z;
[:upper:] :表示大写字符,即A-Z;
[:print:] :表示任何可以被打印出来的字符;
[:punct:] :表示标点符号,即:" ' ? ! # $ 等等;
[:space:] :表示任何会产生空白的字符,包括空格、[Tab]、CR等;
[:xdigit:] :表示16进制的数字类型,因此包括0-9,A-F,a-f;
2.3 grep的一些进阶选项
[~]$ grep [-A] [-B] [--color=auto] '搜索字符串' filename
选项与参数:
-A :后面加数字,为after的意思,除了列出该行外,后续的n行也列出来;
-B :后面加数字,为before的意思,除了列出改行外,前面的n行也列出来;
--color=auto :将要搜索的字符串附加颜色;
2.4 基础正规表示法练习
假设有以下文件:
[~]$ vi regular_express.txt
"Open Source" is a good mechanism to develop programs.
apple is my favorite food.
Football game is not use feet only.
this dress doesn't fit me.
However, this dress is about $ 3183 dollars.
GNU is free air not free beer.
Her hair is very beauty.
I can't finish the test.
Oh! The soup taste good.
motorcycle is cheap than car.
This window is clear.
the symbol '*' is represented as start.
Oh! My god!
The gd software is a library for drafting programs.
You are the best is mean you are the no. 1.
The world is the same with "glad".
I like dog.
google is the best tools for search keyword.
goooooogle yes!
go! go! Let's go.
# I am VBird
示例1:搜索指定字符串
[~]$ grep -n 'the' regular_express.txt --color=auto
示例2:利用中括号来搜索集合字符
如果想要搜索"test"和"taste"两个关键字,我们可以这样来搜索:
[~]$ grep -n '[tae]st' regular_express.txt --color=auto
如果我们想搜索"oo",但不想要前面有"g"的数据怎么做?可以在集合字符中使用反向选择"[^]":
[~]$ grep -n '[^g]oo' regular_express.txt --color=auto
如果"oo"前不想要小写字符,可以这样写:
[~]$ grep -n '[^a-z]oo' regular_express.txt --color=auto
如果字符组是连续的,例如大写/小写/数字等等,就可以使用"[a-zA-Z0-9]"来表示。
由于语系对编码顺序是有影响的,因此也可以使用下面的表示法来测试前面的结果:
[~]$ grep -n '[^[:lower:]]oo' regular_express.txt --color=auto
[~]$ grep -n '[[:digit:]]' regular_express.txt --color=auto
示例3:行首与行尾字符 ^ $
如果只想让"the"在行首的行列出怎么做:
[~]$ grep -n '^the' regular_express.txt
如果想要开头是小写字符的那一行就列出怎么做:
[~]$ grep -n '^[a-z]' regular_express.txt
[~]$ grep -n '^[[:lower:]]' regular_express.txt
如果不想开头是英文字母怎么做:
[~]$ grep -n '^[^a-zA-z]' regular_express.txt
[~]$ grep -n '^[^[:alpha:]]' regular_express.txt
如果想要找出行尾有小数点"."的那一行怎么做:
[~]$ grep -n '\.$' regular_express.txt ## 注意:这里的小数点需要转义
如果想要找出"空白行"怎么做?
[~]$ grep -n '^$' regular_express.txt ## 因为只有行首和行尾,这样就找出空白行了。
假设有一个shell script,空白行和#的那一行是批注,因此想要省略掉这些行,怎么做?
[~]$ grep -v '^$' regular_express.txt | grep -v '^#' regular_express.txt
*示例4:任意一个字符 . 与重复字符 **
在正规表示法"*"并不是通配符:
. :表示一定有一个任意字符;
-
- :表示重复前一个字符,0到无穷次;
如果我们想要找出"g??d"的字符怎么做:
[~]$ grep -n 'g..d' regular_express.txt ## 表示g和d之间必须存在两个字符
""表示重复0个或多个前面的字符,因此"o"表示:拥有空字符或一个o以上的字符。
[~]$ grep -n 'o*' regular_express.txt ## 因为允许空字符,所以将会把所有的数据都打印出来
如果是"oo"呢?第1个"o"必须存在,第2个"o"是可有可无的多个"o",所以,凡是有"o,oo,oooo"等等,都被列出来;同理,当需要至少2个o以上的字符串时,就需要"ooo"。
[~]$ grep -n 'ooo*' regular_express.txt
如果想找出g开头与g结尾的字符串,当中的字符可有可无怎么做?是"gg"吗?"g"表示空字符或一个以上的g,在加上后面的g,所以搜索的内容就是g,gg,ggg,gggg。只要该行中拥有一个以上的g就符合了。
那如何找出g.....g的行?可以使用任意一个字符"."。
[~]$ grep -n 'g.*g' regular_express.txt ## ". *"表示0个或多个任意字符
如果想要找出任意数字的行怎么做:
[~]$ grep -n '[0-9][0-9]*' regular_express.txt ## 虽然[0-9]就可以达到效果,但是希望可以理解这个表达式的意义。
示例5:限定连续正规表示法的字符范围:{}
如果想找到2个o的字符串怎么做:
[~]$ grep -n 'o\{2\}' regular_express.txt ## 因为{ }在shell是有特殊意义的,所以需要转义。
如果想找到g后面接2到5个o的字符串,再接一个g的字符串怎么做:
[~]$ grep -n 'go\{2,5\}g' regular_express.txt
如果想要2个o以上的字符串"gooo...g"呢?除了gooo*g也可以是:
[~]$ grep -n 'go\{2,\}g' regular_express.txt
2.5 基础正规表达式字符汇整
^word :搜索的字符串(word)在行首;
word$ : 搜索的字符串(word)在行尾;
. :表示"一定有一个任意字符"的字符;
\ :转义;
* :重复0个到无穷个前一个RE字符;
[list] :表示字符集合的RE字符,里面列出想搜索的;
[n1-n2]:表示字符集合的RE字符,里面列出想要获取的范围;
[^list] :表示字符集合的RE字符,里面列出不想要的字符串或范围;
\{n,m\} :表示n到m个的"前一个RE字符";
2.6 sed工具
sed本身是一个管道命令,可以分析stdin了。
功能简介:
[~]$ sed [-nefr] [动作]
选项与参数:
-n :使用安静(silent)模式,一般sed中,所有stdin的数据都会被显示。如果使用-n后,只有经过sed特殊处理的那一行或动作才会被显示出来;
-e :直接在指令列模式上进行sed动作编辑;
-f :直接将sed的动作写在一个文件内, -f filename 执行filename的sed动作;
-i :直接修改读取的文件内容,而不是由屏幕输出;
动作说明:[n1[,n2]]fuction
n1,n2 :可以不存在,一般表示"选择进行动作的行数"。例如:需要在10到20行之间进行的动作表示为 10,20[fuction];
fuction 列表:
a :新增,后面接字符串,这些字符串会在新的一行出现(当前的上一行);
c :替换,后面接字符串,这些字符串可以替换n1到n2之间的行;
d :删除;
i :插入,后面接字符串,这些字符串会在新的一行出现(当前上一行);
p :打印,将某个选择的数据打印出来,通常与 -n 一起使用;
s :替换,可以直接进行替换。通常这个s的动作搭配正规表示法。
以行为单位的新增/删除
示例1 :将/etc/passwd的内容列出并打印行号,同时将2-5行删除
[~]$ nl /etc/passwd | sed '2,5d' ## 删除第2行'2d';删除2到最后一行'3,$d'
示例2 :接上示例,在第二行后加上"drink tea?"
[~]$ nl /etc/passwd |sed '2a drink tea?'
以行为单位的替换与显示
示例3 :将2-5行的内容替换为"No 2-5 number"
[~]$ nl /etc/passwd |sed '2,5c No 2-5 number'
示例4 :将/etc/passwd文件内的第5-8行列出来
[~]$ nl /etc/passwd | sed -n '5,8p'
数据的搜索并取代功能
[~]$ sed 's/要被取代的字符串/新的字符串/g'
示例1:查询IP
[~]$ ifconfig en4
示例2:接上一示例,根据'inet '获取结果
[~]$ ifconfig en4 | grep 'inet '
示例3:接上一示例,将IP前面的部分删除
[~]$ ifconfig en4 | grep 'inet ' | sed 's/^.*inet //g'
示例4:接上一示例,将IP后面的部分删除
[~]$ ifconfig en4 | grep 'inet ' | sed 's/^.*inet //g' | sed 's/ *netmask.*$//g'
示例5: /etc/man_db.conf中带有"MAN"的获取出来,删除批注行和空白行;
[~]$ cat /etc/man.conf |grep 'MAN' | sed 's/#.*//g' |sed '/^$/d' ## /^$/ 表示空白行
直接修改文件内容(慎用)
示例6:利用sed将regular_express.txt 内的每一行结尾为"."换成"!"
[~]$ sed -i 's/\.$/\!/g' regular_express.txt
示例7:利用sed直接在regular_express.txt最后一行加入"#This is a test"
[~]$ sed -i '$a # This is a test' regular_express.txt
正规表示法的扩展
例如上面有一个例子是在regular_express.txt中去除空白行与行首为#的行,使用的是
"grep -v '^$' regular_express.txt | grep -v '^#' "
可以简化为:
"egrep -v '$|#' regular_express.txt"
正规表示法扩展有哪些特殊符号?
+ :表示重复1个或1个以上的前一个RE字符; ## egrep -n 'go+d' regular_express.txt
? :表示0个或1个的前一个RE字符; ## egrep -n 'go?d' regular_express.txt
() :找出群组的字符串; ## egrep -n 'g(la|oo)d' regular_express.txt
()+:找出群组的字符串; ## echo AxyzxyzC | egrep 'A(xyz)+C' 意思是找出开头是A,结尾是C,包含1个以上xyz的字符串;
3.文件的格式化与相关处理
3.1 格式化打印:printf
功能简介:
[~]$ printf '打印格式' 实际内容
选项与参数:
\a :警告声音输出;
\b :删除键;
\f :清除屏幕;
\n :输出新的一行;
\r :即enter键;
\t :水平的[tab]键;
\v :垂直的[tab]键;
\xNN :NN为2位数的数字,可以转换数字成为字符;
C语言中,常见的变数格式:
%ns :n是数字,s代表string,即n个字符串;
%ni :n是数字,i代表integer,即n个整数数字;
%N.nf:n和N都为数字,f代表floating。表示加上小数点一个N个字符,小数点后面保留n位;
3.2 awk:数据处理工具
awk比较倾向于一行当中分成数字字段来处理,默认的字段分隔符为"空格键"或"tab键"。
功能简介:
[~]$ awk '条件类型1{动作1}条件类型2{动作2}...' filename
示例1:使用last取出前5行,只取出账号与IP。
[~]$ last -n 5 | awk '{print $1 "\t" $3}' ## $1,$2,$3...表示每一行的每个字段的变量名称。$0则代表一整行的意思。
接下来了解以下awk有哪些变量:
NF :每一行($0)拥有的字段总数;
NR :目前awk处理的是第几行的数据;
FS :分割字符,默认是空格键;
举例来说:/etc/passwd中以冒号作为分隔符,该文件第1个字段是账号,第3个字段是UID。那想要查阅第3栏小于10的数据怎么做:
[~]$ cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t" $3}'
## 这个BEGIN又是什么?它可以预先设定awk的变量!如果我们不加这个关键词,那么当我们读入第一行数据时候,它默认还是以空格键为分隔的!
假设有一下文本:
[~]$ cat text.txt
Name 1st 2nd 3th
tony 20 20 30
tom 10 30 35
jerry 5 45 45
如果想要计算每个人的总额怎么算?还需要格式化输出。
[~]$ cat test.txt | awk 'NR==1{printf "%10s %5s %5s %5s %5s",$1,$2,$3,$4,"Total\n"} NR>=2{printf "%10s %5d %5d %5d %5.2f\n",$1,$2,$3,$4,$1+$2+$3+$4}'
另外,awk的动作{}内也支持if条件,上面的指令可以修改为以下这样:
[~]$ cat test.txt | awk '{if (NR==1) printf "%10s %5s %5s %5s %5s",$1,$2,$3,$4,"Total\n"} {printf "%10s %5d %5d %5d %5.2f\n",$1,$2,$3,$4,$1+$2+$3+$4}'
3.3 文件比对工具
diff
diff用来比对两个文件之间的差异,以行为单位来比对的。
示例:将/etc/passwd备份为passwd.old后,把第4行删除,第6行替换为no line,再另存为passwd.new,怎么做呢?
[~]$ cat passwd.old | sed -e '4d' -e '6c no line' > passwd.new
接下来了解一下diff的使用:
[~]$ diff [-bBi] from-file to-file
选项与参数:
from-file :原始对比文件档名;
to-file :目标对比文件档名;
提示:from-file/to-file可以使用"-"替换,表示"stdin";
-b :忽略一行中仅有多个空白的差异(例如"a b"和"a b"忽略差异);
-B :忽略空白行的差异;
-i :忽略大小写的不同;
cmp
cmp在比对文件的时候,主要是利用字节单位去比对的。
[~]$ cmp [-l] file1 file2
选项与参数:
-l :将所有的不同点的字节出都列出来。预设仅会输出第一个发现的不同点。
patch
将旧的文件升级成新的文件,经常与diff搭配使用。
示例1:制作passwd.old与passwd.new补丁文件
[~]$ diff -Naur passwd.old passwd.new > passwd.patch
[~]$ cat passwd.patch ##可以看到passwd.old到passwd.new做了哪些修改,一般使用diff制作的补丁文件通常使用扩展名.patch。
功能简介:
[~]$ patch -pN < patch_file ##更新;
[~]$ patch -R -pN < patch_file ##还原;
选项与参数:
-p :加"取消几层目录",N为数字;
-R :表示将新的文件还原成原来旧的文件;
示例2:将刚刚制作出来的path file用来更新旧版数据
[~]$ patch -p0 < passed.patch
[~]$ ls -l passwd*
示例3:恢复旧的文件内容
[~]$ patch -R -p0 < passwd.patch
[~]$ ls -l passwd*
因为新旧版的数据是在同一个目录下的,所以是"-p0"。