- 浏览: 595758 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (669)
- oracle (36)
- java (98)
- spring (48)
- UML (2)
- hibernate (10)
- tomcat (7)
- 高性能 (11)
- mysql (25)
- sql (19)
- web (42)
- 数据库设计 (4)
- Nio (6)
- Netty (8)
- Excel (3)
- File (4)
- AOP (1)
- Jetty (1)
- Log4J (4)
- 链表 (1)
- Spring Junit4 (3)
- Autowired Resource (0)
- Jackson (1)
- Javascript (58)
- Spring Cache (2)
- Spring - CXF (2)
- Spring Inject (2)
- 汉字拼音 (3)
- 代理模式 (3)
- Spring事务 (4)
- ActiveMQ (6)
- XML (3)
- Cglib (2)
- Activiti (15)
- 附件问题 (1)
- javaMail (1)
- Thread (19)
- 算法 (6)
- 正则表达式 (3)
- 国际化 (2)
- Json (3)
- EJB (3)
- Struts2 (1)
- Maven (7)
- Mybatis (7)
- Redis (8)
- DWR (1)
- Lucene (2)
- Linux (73)
- 杂谈 (2)
- CSS (13)
- Linux服务篇 (3)
- Kettle (9)
- android (81)
- protocol (2)
- EasyUI (6)
- nginx (2)
- zookeeper (6)
- Hadoop (41)
- cache (7)
- shiro (3)
- HBase (12)
- Hive (8)
- Spark (15)
- Scala (16)
- YARN (3)
- Kafka (5)
- Sqoop (2)
- Pig (3)
- Vue (6)
- sprint boot (19)
- dubbo (2)
- mongodb (2)
最新评论
接下来让我们来将文件进行一些简单的编排吧!底下这些动作可以将你的信息进行排版的动作, 不需要重新以 vim 去编辑,透过数据流重导向配合底下介绍的 printf 功能,以及 awk 命令, 就可以让你的信息以你想要的模样来输出了!试看看吧!
格式化列印: printf
在很多时候,我们可能需要将自己的数据给他格式化输出的! 举例来说,考试卷分数的输出,姓名与科目及分数之间,总是可以稍微作个比较漂亮的版面配置吧? 例如我想要输出底下的样式:
上表的数据主要分成五个栏位,各个栏位之间可使用 tab 或空白键进行分隔。 请将上表的数据转存成为 printf.txt 档名,等一下我们会利用这个文件来进行几个小练习的。 因为每个栏位的原始数据长度其实并非是如此固定的 (Chinese 长度就是比 Name 要多), 而我就是想要如此表示出这些数据,此时,就得需要列印格式管理员 printf 的帮忙了! printf 可以帮我们将数据输出的结果格式化,而且而支持一些特殊的字符~底下我们就来看看!
接下来我们来进行几个常见的练习。假设所有的数据都是一般文字 (这也是最常见的状态),因此最常用来分隔数据的符号就是 [Tab] 啦!因为 [Tab] 按键可以将数据作个整齐的排列!那么如何利用 printf 呢?参考底下这个范例:
由於 printf 并不是管线命令,因此我们得要透过类似上面的功能,将文件内容先提出来给 printf 作为后续的数据才行。 如上所示,我们将每个数据都以 [tab] 作为分隔,但是由於 Chinese 长度太长,导致 English 中间多了一个 [tab] 来将数据排列整齐!啊~结果就看到数据对齐结果的差异了!
另外,在 printf 后续的那一段格式中,%s 代表一个不固定长度的字串,而字串与字串中间就以 \t 这个 [tab] 分隔符号来处理!你要记得的是,由於 \t 与 %s 中间还有空格,因此每个字串间会有一个 [tab] 与一个空白键的分隔喔!
既然每个栏位的长度不固定会造成上述的困扰,那我将每个栏位固定就好啦!没错没错!这样想非常好! 所以我们就将数据给他进行固定栏位长度的设计吧!
上面这一串格式想必您看得很辛苦!没关系!一个一个来解释!上面的格式共分为五个栏位, %10s 代表的是一个长度为 10 个字节的字串栏位,%5i 代表的是长度为 5 个字节的数字栏位,至於那个 %8.2f 则代表长度为 8 个字节的具有小数点的栏位,其中小数点有两个字节宽度。我们可以使用底下的说明来介绍 %8.2f 的意义:
字节宽度: 12345678
%8.2f意义:00000.00
如上所述,全部的宽度仅有 8 个字节,整数部分占有 5 个字节,小数点本身 (.) 占一位,小数点下的位数则有两位。 这种格式经常使用於数值程序的设计中!这样了解乎?自己试看看如果要将小数点位数变成 1 位又该如何处理?
printf 除了可以格式化处理之外,他还可以依据 ASCII 的数字与图形对应来显示数据喔(注3)! 举例来说 16 进位的 45 可以得到什么 ASCII 的显示图 (其实是字节啦)?
printf 的使用相当的广泛喔!包括等一下后面会提到的 awk 以及在 C 程序语言当中使用的萤幕输出, 都是利用 printf 呢!鸟哥这里也只是列出一些可能会用到的格式而已,有兴趣的话,可以自行多作一些测试与练习喔! ^_^
awk:好用的数据处理工具
awk 也是一个非常棒的数据处理工具!相较於 sed 常常作用於一整个行的处理, awk 则比较倾向於一行当中分成数个『栏位』来处理。因此,awk 相当的适合处理小型的数据数据处理呢!awk 通常运行的模式是这样的:
awk 后面接两个单引号并加上大括号 {} 来配置想要对数据进行的处理动作。 awk 可以处理后续接的文件,也可以读取来自前个命令的 standard output 。 但如前面说的, awk 主要是处理『每一行的栏位内的数据』,而默认的『栏位的分隔符号为 "空白键" 或 "[tab]键" 』!举例来说,我们用 last 可以将登陆者的数据取出来,结果如下所示:
若我想要取出帐号与登陆者的 IP ,且帐号与 IP 之间以 [tab] 隔开,则会变成这样:
上表是 awk 最常使用的动作!透过 print 的功能将栏位数据列出来!栏位的分隔则以空白键或 [tab] 按键来隔开。 因为不论哪一行我都要处理,因此,就不需要有 "条件类型" 的限制!我所想要的是第一栏以及第三栏, 但是,第五行的内容怪怪的~这是因为数据格式的问题啊!所以罗~使用 awk 的时候,请先确认一下你的数据当中,如果是连续性的数据,请不要有空格或 [tab] 在内,否则,就会像这个例子这样,会发生误判喔!
另外,由上面这个例子你也会知道,在每一行的每个栏位都是有变量名称的,那就是 $1, $2... 等变量名称。以上面的例子来说, root 是 $1 ,因为他是第一栏嘛!至於 192.168.1.100 是第三栏, 所以他就是 $3 啦!后面以此类推~呵呵!还有个变量喔!那就是 $0 ,$0 代表『一整列数据』的意思~以上面的例子来说,第一行的 $0 代表的就是『root .... 』那一行啊! 由此可知,刚刚上面五行当中,整个 awk 的处理流程是:
1.读入第一行,并将第一行的数据填入 $0, $1, $2.... 等变量当中;
2.依据 "条件类型" 的限制,判断是否需要进行后面的 "动作";
3.做完所有的动作与条件类型;
若还有后续的『行』的数据,则重复上面 1~3 的步骤,直到所有的数据都读完为止。
经过这样的步骤,你会晓得, awk 是『以行为一次处理的单位』, 而『以栏位为最小的处理单位』。好了,那么 awk 怎么知道我到底这个数据有几行?有几栏呢?这就需要 awk 的内建变量的帮忙啦~
我们继续以上面 last -n 5 的例子来做说明,如果我想要:
1.列出每一行的帐号(就是 $1);
2.列出目前处理的行数(就是 awk 内的 NR 变量)
3.并且说明,该行有多少栏位(就是 awk 内的 NF 变量)
则可以这样:
这样可以了解 NR 与 NF 的差别了吧?好了,底下来谈一谈所谓的 "条件类型" 了吧!
awk 的逻辑运算字节
既然有需要用到 "条件" 的类别,自然就需要一些逻辑运算罗~例如底下这些:
值得注意的是那个『 == 』的符号,因为:
1.逻辑运算上面亦即所谓的大於、小於、等於等判断式上面,习惯上是以『 == 』来表示;
2.如果是直接给予一个值,例如变量配置时,就直接使用 = 而已。
好了,我们实际来运用一下逻辑判断吧!举例来说,在 /etc/passwd 当中是以冒号 ":" 来作为栏位的分隔, 该文件中第一栏位为帐号,第三栏位则是 UID。那假设我要查阅,第三栏小於 10 以下的数据,并且仅列出帐号与第三栏, 那么可以这样做:
有趣吧!不过,怎么第一行没有正确的显示出来呢?这是因为我们读入第一行的时候,那些变量 $1, $2... 默认还是以空白键为分隔的,所以虽然我们定义了 FS=":" 了, 但是却仅能在第二行后才开始生效。那么怎么办呢?我们可以预先配置 awk 的变量啊! 利用 BEGIN 这个关键字喔!这样做:
文件比对工具
什么时候会用到文件的比对啊?通常是『同一个套装软件的不同版本之间,比较配置档与原始档的差异』。 很多时候所谓的文件比对,通常是用在 ASCII 纯文字档的比对上的!那么比对文件的命令有哪些?最常见的就是 diff 罗! 另外,除了 diff 比对之外,我们还可以藉由 cmp 来比对非纯文字档!同时,也能够藉由 diff 创建的分析档, 以处理补丁 (patch) 功能的文件呢!就来玩玩先!
diff
diff 就是用在比对两个文件之间的差异的,并且是以行为单位来比对的!一般是用在 ASCII 纯文字档的比对上。 由於是以行为比对的单位,因此 diff 通常是用在同一的文件(或软件)的新旧版本差异上! 举例来说,假如我们要将 /etc/passwd 处理成为一个新的版本,处理方式为: 将第四行删除,第六行则取代成为『no six line』,新的文件放置到 /tmp/test 里面,那么应该怎么做?
接下来讨论一下关於 diff 的用法吧!
用 diff 比对文件真的是很简单喔!不过,你不要用 diff 去比对两个完全不相干的文件,因为比不出个啥咚咚! 另外, diff 也可以比对整个目录下的差异喔!举例来说,我们想要了解一下不同的启动运行等级 (runlevel) 内容有啥不同?假设你已经知道运行等级 3 与 5 的启动脚本分别放置到 /etc/rc3.d 及 /etc/rc5.d , 则我们可以将两个目录比对一下:
我们的 diff 很聪明吧!还可以比对不同目录下的相同档名的内容,这样真的很方便喔~
cmp
相对於 diff 的广泛用途, cmp 似乎就用的没有这么多了~ cmp 主要也是在比对两个文件,他主要利用『位组』单位去比对, 因此,当然也可以比对 binary file 罗~(还是要再提醒喔, diff 主要是以『行』为单位比对, cmp 则是以『位组』为单位去比对,这并不相同!)
看到了吗?第一个发现的不同点在第四行,而且位组数是在第 106 个位组处!这个 cmp 也可以用来比对 binary 啦! ^_^
patch
patch 这个命令与 diff 可是有密不可分的关系啊!我们前面提到,diff 可以用来分辨两个版本之间的差异, 举例来说,刚刚我们所创建的 passwd.old 及 passwd.new 之间就是两个不同版本的文件。 那么,如果要『升级』呢?就是『将旧的文件升级成为新的文件』时,应该要怎么做呢? 其实也不难啦!就是『先比较新旧版本的差异,并将差异档制作成为补丁档,再由补丁档升级旧文件』即可。 举例来说,我们可以这样做测试:
一般来说,使用 diff 制作出来的比较文件通常使用扩展名为 .patch 罗。至於内容就如同上面介绍的样子。 基本上就是以行为单位,看看哪边有一样与不一样的,找到一样的地方,然后将不一样的地方取代掉! 以上面表格为例,新文件看到 - 会删除,看到 + 会加入!好了,那么如何将旧的文件升级成为新的内容呢? 就是将 passwd.old 改成与 passwd.new 相同!可以这样做:
为什么这里会使用 -p0 呢?因为我们在比对新旧版的数据时是在同一个目录下, 因此不需要减去目录啦!如果是使用整体目录比对 (diff 旧目录 新目录) 时, 就得要依据创建 patch 文件所在目录来进行目录的删减罗!
更详细的 patch 用法我们会在后续的第五篇的原始码编译 (第二十二章)再跟大家介绍, 这里仅是介绍给你,我们可以利用 diff 来比对两个文件之间的差异, 更可进一步利用这个功能来制作修补文件 (patch file) ,让大家更容易进行比对与升级呢!很不赖吧! ^_^
文件列印准备: pr
如果你曾经使用过一些图形介面的文书处理软件的话,那么很容易发现,当我们在列印的时候, 可以同时选择与配置每一页列印时的标头吧!也可以配置页码呢!那么,如果我是在 Linux 底下列印纯文字档呢 可不可以具有标题啊?可不可以加入页码啊?呵呵!当然可以啊!使用 pr 就能够达到这个功能了。不过, pr 的参数实在太多了,鸟哥也说不完,一般来说,鸟哥都仅使用最简单的方式来处理而已。举例来说,如果想要列印 /etc/man.config 呢?
上面特殊字体那一行呢,其实就是使用 pr 处理后所造成的标题啦!标题中会有『文件时间』、『文件档名』及『页码』三大项目。 更多的 pr 使用,请参考 pr 的说明啊! ^_^
转自:http://vbird.dic.ksu.edu.tw/linux_basic/0330regularex_4.php
格式化列印: printf
在很多时候,我们可能需要将自己的数据给他格式化输出的! 举例来说,考试卷分数的输出,姓名与科目及分数之间,总是可以稍微作个比较漂亮的版面配置吧? 例如我想要输出底下的样式:
Name Chinese English Math Average DmTsai 80 60 92 77.33 VBird 75 55 80 70.00 Ken 60 90 70 73.33
上表的数据主要分成五个栏位,各个栏位之间可使用 tab 或空白键进行分隔。 请将上表的数据转存成为 printf.txt 档名,等一下我们会利用这个文件来进行几个小练习的。 因为每个栏位的原始数据长度其实并非是如此固定的 (Chinese 长度就是比 Name 要多), 而我就是想要如此表示出这些数据,此时,就得需要列印格式管理员 printf 的帮忙了! printf 可以帮我们将数据输出的结果格式化,而且而支持一些特殊的字符~底下我们就来看看!
[root@www ~]# printf '列印格式' 实际内容 选项与参数: 关於格式方面的几个特殊样式: \a 警告声音输出 \b 倒退键(backspace) \f 清除萤幕 (form feed) \n 输出新的一行 \r 亦即 Enter 按键 \t 水平的 [tab] 按键 \v 垂直的 [tab] 按键 \xNN NN 为两位数的数字,可以转换数字成为字节。 关於 C 程序语言内,常见的变量格式 %ns 那个 n 是数字, s 代表 string ,亦即多少个字节; %ni 那个 n 是数字, i 代表 integer ,亦即多少整数码数; %N.nf 那个 n 与 N 都是数字, f 代表 floating (浮点),如果有小数码数, 假设我共要十个位数,但小数点有两位,即为 %10.2f 罗!
接下来我们来进行几个常见的练习。假设所有的数据都是一般文字 (这也是最常见的状态),因此最常用来分隔数据的符号就是 [Tab] 啦!因为 [Tab] 按键可以将数据作个整齐的排列!那么如何利用 printf 呢?参考底下这个范例:
范例一:将刚刚上头数据的文件 (printf.txt) 内容仅列出姓名与成绩:(用 [tab] 分隔) [root@www ~]# printf '%s\t %s\t %s\t %s\t %s\t \n' $(cat printf.txt) Name Chinese English Math Average DmTsai 80 60 92 77.33 VBird 75 55 80 70.00 Ken 60 90 70 73.33
由於 printf 并不是管线命令,因此我们得要透过类似上面的功能,将文件内容先提出来给 printf 作为后续的数据才行。 如上所示,我们将每个数据都以 [tab] 作为分隔,但是由於 Chinese 长度太长,导致 English 中间多了一个 [tab] 来将数据排列整齐!啊~结果就看到数据对齐结果的差异了!
另外,在 printf 后续的那一段格式中,%s 代表一个不固定长度的字串,而字串与字串中间就以 \t 这个 [tab] 分隔符号来处理!你要记得的是,由於 \t 与 %s 中间还有空格,因此每个字串间会有一个 [tab] 与一个空白键的分隔喔!
既然每个栏位的长度不固定会造成上述的困扰,那我将每个栏位固定就好啦!没错没错!这样想非常好! 所以我们就将数据给他进行固定栏位长度的设计吧!
范例二:将上述数据关於第二行以后,分别以字串、整数、小数点来显示: [root@www ~]# printf '%10s %5i %5i %5i %8.2f \n' $(cat printf.txt |\ > grep -v Name) DmTsai 80 60 92 77.33 VBird 75 55 80 70.00 Ken 60 90 70 73.33
上面这一串格式想必您看得很辛苦!没关系!一个一个来解释!上面的格式共分为五个栏位, %10s 代表的是一个长度为 10 个字节的字串栏位,%5i 代表的是长度为 5 个字节的数字栏位,至於那个 %8.2f 则代表长度为 8 个字节的具有小数点的栏位,其中小数点有两个字节宽度。我们可以使用底下的说明来介绍 %8.2f 的意义:
字节宽度: 12345678
%8.2f意义:00000.00
如上所述,全部的宽度仅有 8 个字节,整数部分占有 5 个字节,小数点本身 (.) 占一位,小数点下的位数则有两位。 这种格式经常使用於数值程序的设计中!这样了解乎?自己试看看如果要将小数点位数变成 1 位又该如何处理?
printf 除了可以格式化处理之外,他还可以依据 ASCII 的数字与图形对应来显示数据喔(注3)! 举例来说 16 进位的 45 可以得到什么 ASCII 的显示图 (其实是字节啦)?
范例三:列出 16 进位数值 45 代表的字节为何? [root@www ~]# printf '\x45\n' E # 这东西也很好玩~他可以将数值转换成为字节,如果你会写 script 的话, # 可以自行测试一下,由 20~80 之间的数值代表的字节是啥喔! ^_^
printf 的使用相当的广泛喔!包括等一下后面会提到的 awk 以及在 C 程序语言当中使用的萤幕输出, 都是利用 printf 呢!鸟哥这里也只是列出一些可能会用到的格式而已,有兴趣的话,可以自行多作一些测试与练习喔! ^_^
awk:好用的数据处理工具
awk 也是一个非常棒的数据处理工具!相较於 sed 常常作用於一整个行的处理, awk 则比较倾向於一行当中分成数个『栏位』来处理。因此,awk 相当的适合处理小型的数据数据处理呢!awk 通常运行的模式是这样的:
root@www ~]# awk '条件类型1{动作1} 条件类型2{动作2} ...' filename
awk 后面接两个单引号并加上大括号 {} 来配置想要对数据进行的处理动作。 awk 可以处理后续接的文件,也可以读取来自前个命令的 standard output 。 但如前面说的, awk 主要是处理『每一行的栏位内的数据』,而默认的『栏位的分隔符号为 "空白键" 或 "[tab]键" 』!举例来说,我们用 last 可以将登陆者的数据取出来,结果如下所示:
[root@www ~]# last -n 5 <==仅取出前五行 root pts/1 192.168.1.100 Tue Feb 10 11:21 still logged in root pts/1 192.168.1.100 Tue Feb 10 00:46 - 02:28 (01:41) root pts/1 192.168.1.100 Mon Feb 9 11:41 - 18:30 (06:48) dmtsai pts/1 192.168.1.100 Mon Feb 9 11:41 - 11:41 (00:00) root tty1 Fri Sep 5 14:09 - 14:10 (00:01)
若我想要取出帐号与登陆者的 IP ,且帐号与 IP 之间以 [tab] 隔开,则会变成这样:
[root@www ~]# last -n 5 | awk '{print $1 "\t" $3}' root 192.168.1.100 root 192.168.1.100 root 192.168.1.100 dmtsai 192.168.1.100 root Fri
上表是 awk 最常使用的动作!透过 print 的功能将栏位数据列出来!栏位的分隔则以空白键或 [tab] 按键来隔开。 因为不论哪一行我都要处理,因此,就不需要有 "条件类型" 的限制!我所想要的是第一栏以及第三栏, 但是,第五行的内容怪怪的~这是因为数据格式的问题啊!所以罗~使用 awk 的时候,请先确认一下你的数据当中,如果是连续性的数据,请不要有空格或 [tab] 在内,否则,就会像这个例子这样,会发生误判喔!
另外,由上面这个例子你也会知道,在每一行的每个栏位都是有变量名称的,那就是 $1, $2... 等变量名称。以上面的例子来说, root 是 $1 ,因为他是第一栏嘛!至於 192.168.1.100 是第三栏, 所以他就是 $3 啦!后面以此类推~呵呵!还有个变量喔!那就是 $0 ,$0 代表『一整列数据』的意思~以上面的例子来说,第一行的 $0 代表的就是『root .... 』那一行啊! 由此可知,刚刚上面五行当中,整个 awk 的处理流程是:
1.读入第一行,并将第一行的数据填入 $0, $1, $2.... 等变量当中;
2.依据 "条件类型" 的限制,判断是否需要进行后面的 "动作";
3.做完所有的动作与条件类型;
若还有后续的『行』的数据,则重复上面 1~3 的步骤,直到所有的数据都读完为止。
经过这样的步骤,你会晓得, awk 是『以行为一次处理的单位』, 而『以栏位为最小的处理单位』。好了,那么 awk 怎么知道我到底这个数据有几行?有几栏呢?这就需要 awk 的内建变量的帮忙啦~
变量名称 代表意义 NF 每一行 ($0) 拥有的栏位总数 NR 目前 awk 所处理的是『第几行』数据 FS 目前的分隔字节,默认是空白键
我们继续以上面 last -n 5 的例子来做说明,如果我想要:
1.列出每一行的帐号(就是 $1);
2.列出目前处理的行数(就是 awk 内的 NR 变量)
3.并且说明,该行有多少栏位(就是 awk 内的 NF 变量)
则可以这样:
[root@www ~]# last -n 5| awk '{print $1 "\t lines: " NR "\t columns: " NF}' root lines: 1 columns: 10 root lines: 2 columns: 10 root lines: 3 columns: 10 dmtsai lines: 4 columns: 10 root lines: 5 columns: 9 # 注意喔,在 awk 内的 NR, NF 等变量要用大写,且不需要有钱字号 $ 啦!
这样可以了解 NR 与 NF 的差别了吧?好了,底下来谈一谈所谓的 "条件类型" 了吧!
awk 的逻辑运算字节
既然有需要用到 "条件" 的类别,自然就需要一些逻辑运算罗~例如底下这些:
运算单元 代表意义 > 大於 < 小於 >= 大於或等於 <= 小於或等於 == 等於 != 不等於
值得注意的是那个『 == 』的符号,因为:
1.逻辑运算上面亦即所谓的大於、小於、等於等判断式上面,习惯上是以『 == 』来表示;
2.如果是直接给予一个值,例如变量配置时,就直接使用 = 而已。
好了,我们实际来运用一下逻辑判断吧!举例来说,在 /etc/passwd 当中是以冒号 ":" 来作为栏位的分隔, 该文件中第一栏位为帐号,第三栏位则是 UID。那假设我要查阅,第三栏小於 10 以下的数据,并且仅列出帐号与第三栏, 那么可以这样做:
[root@www ~]# cat /etc/passwd | \ > awk '{FS=":"} $3 < 10 {print $1 "\t " $3}' root:x:0:0:root:/root:/bin/bash bin 1 daemon 2 ....(以下省略)....
有趣吧!不过,怎么第一行没有正确的显示出来呢?这是因为我们读入第一行的时候,那些变量 $1, $2... 默认还是以空白键为分隔的,所以虽然我们定义了 FS=":" 了, 但是却仅能在第二行后才开始生效。那么怎么办呢?我们可以预先配置 awk 的变量啊! 利用 BEGIN 这个关键字喔!这样做:
[root@www ~]# cat /etc/passwd | \ > awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t " $3}' root 0 bin 1 daemon 2 ......(以下省略)......
文件比对工具
什么时候会用到文件的比对啊?通常是『同一个套装软件的不同版本之间,比较配置档与原始档的差异』。 很多时候所谓的文件比对,通常是用在 ASCII 纯文字档的比对上的!那么比对文件的命令有哪些?最常见的就是 diff 罗! 另外,除了 diff 比对之外,我们还可以藉由 cmp 来比对非纯文字档!同时,也能够藉由 diff 创建的分析档, 以处理补丁 (patch) 功能的文件呢!就来玩玩先!
diff
diff 就是用在比对两个文件之间的差异的,并且是以行为单位来比对的!一般是用在 ASCII 纯文字档的比对上。 由於是以行为比对的单位,因此 diff 通常是用在同一的文件(或软件)的新旧版本差异上! 举例来说,假如我们要将 /etc/passwd 处理成为一个新的版本,处理方式为: 将第四行删除,第六行则取代成为『no six line』,新的文件放置到 /tmp/test 里面,那么应该怎么做?
[root@www ~]# mkdir -p /tmp/test <==先创建测试用的目录 [root@www ~]# cd /tmp/test [root@www test]# cp /etc/passwd passwd.old [root@www test]# cat /etc/passwd | \ > sed -e '4d' -e '6c no six line' > passwd.new # 注意一下, sed 后面如果要接超过两个以上的动作时,每个动作前面得加 -e 才行! # 透过这个动作,在 /tmp/test 里面便有新旧的 passwd 文件存在了!
接下来讨论一下关於 diff 的用法吧!
[root@www ~]# diff [-bBi] from-file to-file 选项与参数: from-file :一个档名,作为原始比对文件的档名; to-file :一个档名,作为目的比对文件的档名; 注意,from-file 或 to-file 可以 - 取代,那个 - 代表『Standard input』之意。 -b :忽略一行当中,仅有多个空白的差异(例如 "about me" 与 "about me" 视为相同 -B :忽略空白行的差异。 -i :忽略大小写的不同。 范例一:比对 passwd.old 与 passwd.new 的差异: [root@www test]# diff passwd.old passwd.new 4d3 <==左边第四行被删除 (d) 掉了,基准是右边的第三行 < adm:x:3:4:adm:/var/adm:/sbin/nologin <==这边列出左边(<)文件被删除的那一行内容 6c5 <==左边文件的第六行被取代 (c) 成右边文件的第五行 < sync:x:5:0:sync:/sbin:/bin/sync <==左边(<)文件第六行内容 --- > no six line <==右边(>)文件第五行内容 # 很聪明吧!用 diff 就把我们刚刚的处理给比对完毕了!
用 diff 比对文件真的是很简单喔!不过,你不要用 diff 去比对两个完全不相干的文件,因为比不出个啥咚咚! 另外, diff 也可以比对整个目录下的差异喔!举例来说,我们想要了解一下不同的启动运行等级 (runlevel) 内容有啥不同?假设你已经知道运行等级 3 与 5 的启动脚本分别放置到 /etc/rc3.d 及 /etc/rc5.d , 则我们可以将两个目录比对一下:
[root@www ~]# diff /etc/rc3.d/ /etc/rc5.d/ Only in /etc/rc3.d/: K99readahead_later Only in /etc/rc5.d/: S96readahead_later
我们的 diff 很聪明吧!还可以比对不同目录下的相同档名的内容,这样真的很方便喔~
cmp
相对於 diff 的广泛用途, cmp 似乎就用的没有这么多了~ cmp 主要也是在比对两个文件,他主要利用『位组』单位去比对, 因此,当然也可以比对 binary file 罗~(还是要再提醒喔, diff 主要是以『行』为单位比对, cmp 则是以『位组』为单位去比对,这并不相同!)
[root@www ~]# cmp [-s] file1 file2 选项与参数: -s :将所有的不同点的位组处都列出来。因为 cmp 默认仅会输出第一个发现的不同点。 范例一:用 cmp 比较一下 passwd.old 及 passwd.new [root@www test]# cmp passwd.old passwd.new passwd.old passwd.new differ: byte 106, line 4
看到了吗?第一个发现的不同点在第四行,而且位组数是在第 106 个位组处!这个 cmp 也可以用来比对 binary 啦! ^_^
patch
patch 这个命令与 diff 可是有密不可分的关系啊!我们前面提到,diff 可以用来分辨两个版本之间的差异, 举例来说,刚刚我们所创建的 passwd.old 及 passwd.new 之间就是两个不同版本的文件。 那么,如果要『升级』呢?就是『将旧的文件升级成为新的文件』时,应该要怎么做呢? 其实也不难啦!就是『先比较新旧版本的差异,并将差异档制作成为补丁档,再由补丁档升级旧文件』即可。 举例来说,我们可以这样做测试:
范例一:以 /tmp/test 内的 passwd.old 与 passwd.new 制作补丁文件 [root@www test]# diff -Naur passwd.old passwd.new > passwd.patch [root@www test]# cat passwd.patch --- passwd.old 2009-02-10 14:29:09.000000000 +0800 <==新旧文件的资讯 +++ passwd.new 2009-02-10 14:29:18.000000000 +0800 @@ -1,9 +1,8 @@ <==新旧文件要修改数据的界定范围,旧档在 1-9 行,新档在 1-8 行 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin -adm:x:3:4:adm:/var/adm:/sbin/nologin <==左侧文件删除 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin -sync:x:5:0:sync:/sbin:/bin/sync <==左侧文件删除 +no six line <==右侧新档加入 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
一般来说,使用 diff 制作出来的比较文件通常使用扩展名为 .patch 罗。至於内容就如同上面介绍的样子。 基本上就是以行为单位,看看哪边有一样与不一样的,找到一样的地方,然后将不一样的地方取代掉! 以上面表格为例,新文件看到 - 会删除,看到 + 会加入!好了,那么如何将旧的文件升级成为新的内容呢? 就是将 passwd.old 改成与 passwd.new 相同!可以这样做:
[root@www ~]# patch -pN < patch_file <==升级 [root@www ~]# patch -R -pN < patch_file <==还原 选项与参数: -p :后面可以接『取消几层目录』的意思。 -R :代表还原,将新的文件还原成原来旧的版本。 范例二:将刚刚制作出来的 patch file 用来升级旧版数据 [root@www test]# patch -p0 < passwd.patch patching file passwd.old [root@www test]# ll passwd* -rw-r--r-- 1 root root 1929 Feb 10 14:29 passwd.new -rw-r--r-- 1 root root 1929 Feb 10 15:12 passwd.old <==文件一模一样! 范例三:恢复旧文件的内容 [root@www test]# patch -R -p0 < passwd.patch [root@www test]# ll passwd* -rw-r--r-- 1 root root 1929 Feb 10 14:29 passwd.new -rw-r--r-- 1 root root 1986 Feb 10 15:18 passwd.old # 文件就这样恢复成为旧版本罗
为什么这里会使用 -p0 呢?因为我们在比对新旧版的数据时是在同一个目录下, 因此不需要减去目录啦!如果是使用整体目录比对 (diff 旧目录 新目录) 时, 就得要依据创建 patch 文件所在目录来进行目录的删减罗!
更详细的 patch 用法我们会在后续的第五篇的原始码编译 (第二十二章)再跟大家介绍, 这里仅是介绍给你,我们可以利用 diff 来比对两个文件之间的差异, 更可进一步利用这个功能来制作修补文件 (patch file) ,让大家更容易进行比对与升级呢!很不赖吧! ^_^
文件列印准备: pr
如果你曾经使用过一些图形介面的文书处理软件的话,那么很容易发现,当我们在列印的时候, 可以同时选择与配置每一页列印时的标头吧!也可以配置页码呢!那么,如果我是在 Linux 底下列印纯文字档呢 可不可以具有标题啊?可不可以加入页码啊?呵呵!当然可以啊!使用 pr 就能够达到这个功能了。不过, pr 的参数实在太多了,鸟哥也说不完,一般来说,鸟哥都仅使用最简单的方式来处理而已。举例来说,如果想要列印 /etc/man.config 呢?
[root@www ~]# pr /etc/man.config 2007-01-06 18:24 /etc/man.config Page 1 # # Generated automatically from man.conf.in by the # configure script. .....以下省略......
上面特殊字体那一行呢,其实就是使用 pr 处理后所造成的标题啦!标题中会有『文件时间』、『文件档名』及『页码』三大项目。 更多的 pr 使用,请参考 pr 的说明啊! ^_^
转自:http://vbird.dic.ksu.edu.tw/linux_basic/0330regularex_4.php
发表评论
文章已被作者锁定,不允许评论。
-
Linux ubuntu配置SSH免密登陆
2017-05-05 16:15 4611、安装 Ubuntu14.04默认安装了ssh-client ... -
Linux ubuntu虚拟机连接上网总结
2017-05-05 13:37 5111.首先查看主机的ip信息 ipconfig /all ... -
Linux七个运行级别
2015-03-03 09:20 542运行级别就是操作系统当前正在运行的功能级别。级别是从0到6,具 ... -
第二十四章 CentOS 系统配置工具: setup
2014-10-30 20:05 671系统配置除了使用手动 ... -
第二十二章 启动过程的问题解决
2014-10-28 19:34 421很多时候,我们可能因 ... -
第二十二章 Boot Loader: Grub
2014-10-27 19:44 567在看完了前面的整个启 ... -
第二十二章 核心与核心模块
2014-10-23 19:28 342谈完了整个启动的流程 ... -
第二十二章 Linux 的启动流程分析
2014-10-22 20:08 389启动不是只要按一下电 ... -
第二十一章 管理的抉择:RPM 还是 Tarball
2014-10-20 19:24 499这一直是个有趣的问题 ... -
第二十一章 YUM 线上升级机制
2014-10-15 19:33 525我们在本章一开始的地方谈到过 yum 这玩意儿,这个 yum ... -
第二十一章 SRPM 的使用 : rpmbuild
2014-10-14 19:44 955谈完了 RPM 类型的软件之后,再来我们谈一谈包含了 Sour ... -
第二十一章 RPM 软件管理程序: rpm
2014-10-13 20:10 449RPM 的使用其实不难,只要使用 rpm 这个命令即可!鸟哥最 ... -
第二十章 函式库管理
2014-10-13 19:25 475在我们的 Linux 操作系统 ... -
第二十章 Tarball 的管理与建议
2014-10-10 19:54 491在我们知道了原始码的 ... -
第二十章 用 make 进行巨集编译
2014-10-09 20:04 529在本章一开始我们提到过 make 的功能是可以简化编译过程里面 ... -
第二十章 开放源码的软件安装与升级简介
2014-10-09 19:47 439如果鸟哥想要在我的 Lin ... -
第十九章 分析登录文件
2014-10-08 19:34 408登录文件的分析是很重要的!你可以自行以 vi 进入登录文 ... -
第十九章 登录文件的轮替(logrotate)
2014-10-08 19:28 511假设我们已经将登 ... -
第十九章 syslogd :记录登录文件的服务
2014-09-28 20:11 678刚刚提到说 Linux 的登录文件主要是由 syslogd 在 ... -
第十八章 系统开启的服务
2014-09-25 19:33 715好了,现在假设你已经知道了 daemons 的启动文件放置的目 ...
相关推荐
以下是关于Python文件处理和数据格式化的详细知识点: 1. **文件处理方式**: - Python可以以文本(默认)和二进制两种方式处理文件。文本模式下,数据按字符流处理;二进制模式下,数据按字节流处理。 - 使用...
**文件的格式化与相关处理** 除了正规表示法,还有一些工具用于处理文件格式,如`diff`用于比较文件差异,`cmp`检查文件是否相同,`patch`用于应用补丁,以及`pr`用于将文本格式化为适合打印的形式。 **档案比对...
第12章主要介绍了文件处理的概念,特别是如何在C语言中进行文件操作。以下是对标题、描述和部分内容的详细解释: 1. **文件处理的重要性**: 文件处理使得数据管理变得简单且灵活。同一程序可以处理具有相同数据...
`SaveAs`允许指定新的文件名和路径,以及选择不同的文件格式,如`.xlsx`, `.csv`, `.pdf`等。 3. **读取文件内容**: 要读取工作表中的数据,你可以使用`Range`对象和`Value`属性。例如,`Range("A1").Value`获取...
本资源包含该书的课后答案,涵盖了从第一章到第十二章的全部练习题目,对于学习者来说,是一份极具价值的学习资料。 首先,我们要明确数字图像处理的核心内容包括图像的获取、表示、分析和变换。在第一部分,书中会...
但是,我可以根据《C++ Primer》第五版的内容结构以及一般C++的学习顺序,为读者提供第12章可能涵盖的知识点,并对C++11标准中的相关概念进行介绍。 第12章通常会涉及C++中的输入输出库(I/O库),这是C++编程中必...
《C语言程序设计:第12章 文件》 在C语言中,文件是程序与外部存储之间交换数据的重要手段。本章主要介绍了文件的基本概念、文本文件与二进制文件的区别,以及缓冲文件系统的运作机制。 12.1 文件的基本概念 文件...
- 如果要写入的数据结构如列表,可以先转换为字符串再写入,或者利用`pprint.pprint()`进行格式化输出后再写入。 3. **异常处理** - Python中异常处理使用`try-except`语句,例如: ```python try: # 可能抛出...
本章主要讲解了C语言中文件操作的基本概念、方法和实践,包括文件概述、文件的打开与关闭、文件的定位与检测、文件的读写以及通过实例进一步阐述这些概念。 12.1 文件概述 文件是存储在外部介质如磁盘上的一组相关...
而在数据库中,文件则是一个结构化的记录集合,每个记录都有其特定的格式和含义。 文件类型主要分为两类:操作系统的文件和数据库文件。操作系统的文件通常是无结构的,而数据库文件则包含有结构的记录。根据记录的...
第十三章 文件 对数据的管理无论是用数组还是链表,都是存储在内存中的,程序结束后都会丢失,下一次运行程序时,要重新输入或运算生成数据。要把程序运行的数据保存起来以便下次运行继续使用,在计算机中持久保存...
2. **第十二章:ASP.NET AJAX**:介绍了如何利用ASP.NET AJAX扩展动态Web应用程序,实现异步交互,提升用户体验。源码中可能包含UpdatePanel、ScriptManager等组件的实例,展示了AJAX在实际项目中的应用。 3. **第...
第0章 计算机概论 第1章 Linux是什么 第2章 Linux 如何学习 第3章 主机规划与磁盘分区 第4章 安装Centos5.x 与多重引导小技巧 ...第12章 正规表示法与文件格式化处理 第13章 学习Shell Scripts ........
第12章 正则表达式与文件格式化处理 第13章 学习shell script 第四部分 Linux使用者管理 第14章 Linux账号管理与ACL权限设置 第15章 磁盘配额(Quota)与高级文件系统管理 第16章 例行性工作(crontab) 第17章 ...
第12章:类与对象 这一章讲解了面向对象编程的基础,包括类的定义、对象的创建以及封装的概念。类是数据和操作的集合,用于模拟现实世界中的实体。对象则是类的实例,拥有类定义的属性和行为。此外,还介绍了构造...
第12章 文件处理函数 第13章 图形计算与处理函数 第14章 格式化函数 第15章 对话框函数 第16章 打印机函数 第17章 COM实用函数 第18章 窗口控制实用程序 第19章 菜单函数 第20章 向后兼容例程 第21章 行为...
《微机接口技术与虚拟仪器设计》第9章主要探讨的是文件I/O(Input/Output)操作,这是在数据采集和测试系统中至关重要的部分。LabVIEW,即Laboratory Virtual Instrument Engineering Workbench,是一个图形化编程...
MATLAB 7.0 基础教程课后答案第11章 MATLAB 是一种高效的编程语言,...当要在 MATLAB 与其它程序之间交换数据,或者人们要检查与修改文件中的数据时,就应该使用格式化 I/O 操作,否则,就应该使用非格式化 I/O 操作。
文件的读写主要是通过格式化函数`fscanf()`和`fprintf()`实现。`fscanf()`用于从文件中读取数据,`fprintf()`则用于向文件中写入数据。它们的使用格式类似于标准的输入输出函数`scanf()`和`printf()`,但接受一个...
第12章 文件处理函数 第13章 图形计算与处理函数 第14章 格式化函数 第15章 对话框函数 第16章 打印机函数 第17章 COM实用函数 第18章 窗口控制实用程序 第19章 菜单函数 第20章 向后兼容例程 第21章 行为...