[root@station230 tmp]# vncviewer 192.168.2.253
高级文件管理命令:
cat主要有三大功能:
1.一次显示整个文件。$ cat filename
2.从键盘创建一个文件。$ cat > filename
只能创建新文件,不能编辑已有文件.
3.将几个文件合并为一个文件: $cat file1 file2 > file
参数:
-n 或 --number 由 1 开始对所有输出的行数编号
-b 或 --number-nonblank 和 -n 相似,只不过对于空白行不编号
-s 或 --squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行
-v 或 --show-nonprinting
例:
把 textfile1 的档案内容加上行号后输入 textfile2 这个档案里
cat -n textfile1 > textfile2
把 textfile1 和 textfile2 的档案内容加上行号(空白行不加)之后将内容附加到 textfile3 里。
cat -b textfile1 textfile2 >> textfile3
把test.txt文件扔进垃圾箱,赋空值test.txt
cat /dev/null > /etc/test.txt
cat :
[root@station230 tmp]# cat a //查看一个文件
haha
[root@station230 tmp]# cat a > a.txt 添加a到一个文件中会覆盖之前的内容
[root@station230 tmp]# cat a.txt
haha
[root@station230 tmp]# cat a >> a.txt 追加,不会覆盖之前的内容
[root@station230 tmp]# cat a.txt
haha
haha
[root@station230 tmp]# cat -n a.txt 显示内容和行号
1 haha
2 haha
[root@station230 tmp]# cat -b a.txt //不显示空行行号但是空格是显示的
1 haha
2 haha
3 haha
[root@station230 tmp]# cat -bs a.txt //把多个空行合并成1行
1 haha
2 haha
3 haha
[root@station230 tmp]# cat b.txt
heihei
1111111
2222222
[root@station230 tmp]# tac b.txt //倒序显示
2222222
1111111
heihei
===============================================
[root@station230 tmp]# cat a.txt | grep -v ^$ //不显示空行 ^$ 为显示空行 -v表示取反
haha
haha
haha
================================================
tr:
只能替换单个字符
[root@station230 tmp]# cat a.txt | tr 'h' 'A' //讲所有的h替换成A
AaAa
AaAa
AaAa
[root@station230 tmp]# cat a.txt | tr 'a-z' 'A-Z' //将所有的小写字符换成大写
HAHA
HAHA
HAHA
cut:命令
1 一两句话描述一下cut命令吧!
正如其名,cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。
cut是以每一行为一个处理对象的,这种机制和sed是一样的。(关于sed的入门文章将在近期发布)
2 cut一般以什么为依据呢? 也就是说,我怎么告诉cut我想定位到的剪切内容呢?
cut命令主要是接受三个定位方法:
第一,字节(bytes),用选项-b
第二,字符(characters),用选项-c
第三,域(fields),用选项-f 指定第几部分
第四,-d指定分割符
事例:
[root@station230 tmp]# cat c.txt
haha heihei nihao 4444
haha heihei nihao 4444
haha heihei nihao 4444
[root@station230 tmp]# cut -d " " -f 2 c.txt //-d 指定分隔符 -f指定取第几列
heihei
heihei
heihei
[root@station230 tmp]# cut -d " " -f 1,3 c.txt //取第1和第3列
haha nihao
haha nihao
haha nihao
[root@station230 tmp]# cut -d " " -f 3- c.txt //取第三列以后的所有字段
nihao 4444
nihao 4444
nihao 4444
具体事例:
取本机ip地址 192。168。1。253
方法一:
[root@station230 tmp]# ifconfig eth0 | grep Bca | cut -d : -f 2 | cut -d ' ' -f 1
192.168.2.253
方法二:
[root@station230 tmp]# cat -n /etc/sysconfig/network-scripts/ifcfg-eth0 | grep 11 | cut -d = -f 2
192.168.2.253
补充
1 以“字节”定位,给个最简单的例子?
举个例子吧,当你执行ps命令时,会输出类似如下的内容:
[rocrocket@rocrocket programming]$ who
rocrocket :0 2009-01-08 11:07
rocrocket pts/0 2009-01-08 11:23 (:0.0)
rocrocket pts/1 2009-01-08 14:15 (:0.0)
如果我们想提取每一行的第3个字节,就这样:
[rocrocket@rocrocket programming]$ who|cut -b 3
c
c
c
看明白了吧,-b后面可以设定要提取哪一个字节,其实-b和3之间没有空格也是可以的,但推荐有空格:)
2 如果“字节”定位中,我想提取第3,第4、第5和第8个字节,怎么办?
-b支持形如3-5的写法,而且多个定位之间用逗号隔开就成了。看看例子吧:
[rocrocket@rocrocket programming]$ who|cut -b 3-5,8
croe
croe
croe
但有一点要注意,cut命令如果使用了-b选项,那么执行此命令时,cut会先把-b后面所有的定位进行从小到大排序,然后再提取。可不能颠倒定位的顺序哦。这个例子就可以说明这个问题:
[rocrocket@rocrocket programming]$ who|cut -b 8,3-5
croe
croe
croe
3 还有哪些类似“3-5”这样的小技巧,列举一下吧!
[rocrocket@rocrocket programming]$ who
rocrocket :0 2009-01-08 11:07
rocrocket pts/0 2009-01-08 11:23 (:0.0)
rocrocket pts/1 2009-01-08 14:15 (:0.0)
[rocrocket@rocrocket programming]$ who|cut -b -3
roc
roc
roc
[rocrocket@rocrocket programming]$ who|cut -b 3-
crocket :0 2009-01-08 11:07
crocket pts/0 2009-01-08 11:23 (:0.0)
crocket pts/1 2009-01-08 14:15 (:0.0)
想必你也看到了,-3表示从第一个字节到第三个字节,而3-表示从第三个字节到行尾。如果你细心,你可以看到这两种情况下,都包括了第三个字节“c”。
如果我执行who|cut -b -3,3-,你觉得会如何呢?答案是输出整行,不会出现连续两个重叠的c的。看:
[rocrocket@rocrocket programming]$ who|cut -b -3,3-
rocrocket :0 2009-01-08 11:07
rocrocket pts/0 2009-01-08 11:23 (:0.0)
rocrocket pts/1 2009-01-08 14:15 (:0.0)
4 给个以字符为定位标志的最简单的例子吧!
下面例子你似曾相识,提取第3,第4,第5和第8个字符:
[rocrocket@rocrocket programming]$ who|cut -c 3-5,8
croe
croe
croe
不过,看着怎么和-b没有什么区别啊?莫非-b和-c作用一样? 其实不然,看似相同,只是因为这个例子举的不好,who输出的都是单字节字符,所以用-b和-c没有区别,如果你提取中文,区别就看出来了,来,看看中文提取的情况:
[rocrocket@rocrocket programming]$ cat cut_ch.txt
星期一
星期二
星期三
星期四
[rocrocket@rocrocket programming]$ cut -b 3 cut_ch.txt
?
?
?
?
[rocrocket@rocrocket programming]$ cut -c 3 cut_ch.txt
一
二
三
四
看到了吧,用-c则会以字符为单位,输出正常;而-b只会傻傻的以字节(8位二进制位)来计算,输出就是乱码。
既然提到了这个知识点,就再补充一句,如果你学有余力,就提高一下。
当遇到多字节字符时,可以使用-n选项,-n用于告诉cut不要将多字节字符拆开。例子如下:
[rocrocket@rocrocket programming]$ cat cut_ch.txt |cut -b 2
?
?
?
?
[rocrocket@rocrocket programming]$ cat cut_ch.txt |cut -nb 2
[rocrocket@rocrocket programming]$ cat cut_ch.txt |cut -nb 1,2,3
星
星
星
星
5 域是怎么回事呢?解释解释:)
为什么会有“域”的提取呢,因为刚才提到的-b和-c只能在固定格式的文档中提取信息,而对于非固定格式的信息则束手无策。这时候“域”就派上用场了。
(下面的讲解内容是在假设你对/etc/passwd文件的内容和组织形式比较了解的情况下进行的。)
如果你观察过/etc/passwd文件,你会发现,它并不像who的输出信息那样具有固定格式,而是比较零散的排放。但是,冒号在这个文件的每一行中都起到了非常重要的作用,冒号用来隔开每一个项。
我们很幸运,cut命令提供了这样的提取方式,具体的说就是设置“间隔符”,再设置“提取第几个域”,就OK了!
以/etc/passwd的前五行内容为例:
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5
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
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5|cut -d : -f 1
root
bin
daemon
adm
lp
看到了吧,用-d来设置间隔符为冒号,然后用-f来设置我要取的是第一个域,再按回车,所有的用户名就都列出来了!呵呵 有成就感吧!
当然,在设定-f时,也可以使用例如3-5或者4-类似的格式:
[rorocket@rocrocket programming]$ cat /etc/passwd|head -n 5|cut -d : -f 1,3-5
root:0:0:root
bin:1:1:bin
daemon:2:2:daemon
adm:3:4:adm
lp:4:7:lp
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5|cut -d : -f 1,3-5,7
root:0:0:root:/bin/bash
bin:1:1:bin:/sbin/nologin
daemon:2:2:daemon:/sbin/nologin
adm:3:4:adm:/sbin/nologin
lp:4:7:lp:/sbin/nologin
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5|cut -d : -f -2
root:x
bin:x
daemon:x
adm:x
lp:x
6 如果遇到空格和制表符时,怎么分辨呢?我觉得有点乱,怎么办?
有时候制表符确实很难辨认,有一个方法可以看出一段空格到底是由若干个空格组成的还是由一个制表符组成的。
[rocrocket@rocrocket programming]$ cat tab_space.txt
this is tab finish.
this is several space finish.
[rocrocket@rocrocket programming]$ sed -n l tab_space.txt
this is tab\tfinish.$
this is several space finish.$
看到了吧,如果是制表符(TAB),那么会显示为\t符号,如果是空格,就会原样显示。
通过此方法即可以判断制表符和空格了。
注意,上面sed -n后面的字符是L的小写字母哦,不要看错。(字母l、数字1还有或运算|真是难分辨啊…,看来这三个比制表符还难分辨…)
7 我应该在cut -d中用什么符号来设定制表符或空格呢?
悄悄的告诉你,cut的-d选项的默认间隔符就是制表符,所以当你就是要使用制表符的时候,完全就可以省略-d选项,而直接用-f来取域就可以了!放心,相信我!
如果你设定一个空格为间隔符,那么就这样:
[rocrocket@rocrocket programming]$ cat tab_space.txt |cut -d ' ' -f 1
this
this
注意,两个单引号之间可确实要有一个空格哦,不能偷懒。
而且,你只能在-d后面设置一个空格,可不许设置多个空格,因为cut只允许间隔符是一个字符。
[rocrocket@rocrocket programming]$ cat tab_space.txt |cut -d ' ' -f 1
cut: the delimiter must be a single character
Try `cut --help' for more information.
8 我想将ps和cut命令配合使用时,怎么总是在最后两行出现重复现象?
这个问题的具体描述是如下这样的。
当cut和ps配合时:
[rocrocket@rocrocket programming]$ ps
PID TTY TIME CMD
2977 pts/0 00:00:00 bash
5032 pts/0 00:00:00 ps
[rocrocket@rocrocket programming]$ ps|cut -b 3
P
9
0
0
看,最后的0重复了两次!!而且,我也试过ps ef或ps aux均有此问题。
而当ps和其他命令配合时,均无此问题,例如cut和who配合则正常:
[rocrocket@rocrocket programming]$ who
rocrocket :0 2009-01-08 11:07
rocrocket pts/0 2009-01-08 11:23 (:0.0)
rocrocket pts/1 2009-01-08 14:15 (:0.0)
[rocrocket@rocrocket programming]$ who|cut -b3
c
c
c
其实这个问题是这样的,ps|cut会自身创建一个进程,所以当ps时也会提取出这个进程,然后通过管道输出到cut,所以cut截取后,就多出了一行,之所以会重复上一行内容,是由于我们恰巧取到了和上一行内容相同的字符而已。
你测试下执行ps和ps|cat就知道原因了!:)
9 cut有哪些缺陷和不足?
猜出来了吧?对,就是在处理多空格时。
如果文件里面的某些域是由若干个空格来间隔的,那么用cut就有点麻烦了,因为cut只擅长处理“以一个字符间隔”的文本内容。
wc的用法:
wc -c filename:显示一个文件的字节数
wc -m filename:显示一个文件的字符数
wc -l filename:显示一个文件的行数
wc -L filename:显示一个文件中的最长行的长度
wc -w filename:显示一个文件的字数
[rocrocket@rocrocket programming]$ cat wc1.txt
1 2
34 5
你好
[rocrocket@rocrocket programming]$ wc -c wc1.txt
16 wc1.txt
[rocrocket@rocrocket programming]$ wc -m wc1.txt
12 wc1.txt
[rocrocket@rocrocket programming]$ wc -l wc1.txt
3 wc1.txt
[rocrocket@rocrocket programming]$ wc -L wc1.txt
4 wc1.txt
[rocrocket@rocrocket programming]$ wc -w wc1.txt
5 wc1.txt
uniq:命令
该命令各选项含义如下:、
– c 显示输出中,在每行行首加上本行在文件中出现的次数。它可取代- u和- d选项。
– d 只显示重复行。
– u 只显示文件中不重复的各行。
– n 前n个字段与每个字段前的空白一起被忽略。一个字段是一个非空格、非制表符的字符串,彼此由制表符和空格隔开(字段从0开始编号)。
+ n 前n个字符被忽略,之前的字符被跳过(字符从0开始编号)。
– f n 与- n相同,这里n是字段数。
– s n 与+n相同,这里n是字符数。
[root@station230 tmp]# cat c.txt | uniq
haha heihei nihao 4444
1111111111111111111111
haha heihei nihao 4444
[root@station230 tmp]# cat c.txt | uniq -c
2 haha heihei nihao 4444
1 1111111111111111111111
1 haha heihei nihao 4444
[root@station230 tmp]# cat c.txt | uniq -d
haha heihei nihao 4444
[root@station230 tmp]# cat c.txt | uniq -u
1111111111111111111111
haha heihei nihao 4444
例子:
统计/bin和/usr/bin目录下有多少个重复的命令
[root@station230 tmp]# ls /bin/ /usr/bin/ | sort | uniq -d | wc -l
13
sort:排序
1 sort的工作原理
sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。
[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
2 sort的-u选项
它的作用很简单,就是在输出行中去除重复行。
[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
pear
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
pear
[rocrocket@rocrocket programming]$ sort -u seq.txt
apple
banana
orange
pear
pear由于重复被-u选项无情的删除了。
3 sort的-r选项
sort默认的排序方式是升序,如果想改成降序,就加个-r就搞定了。
[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort number.txt
1
2
3
4
5
[rocrocket@rocrocket programming]$ sort -r number.txt
5
4
3
2
1
4 sort的-o选项
由于sort默认是把结果输出到标准输出,所以需要用重定向才能将结果写入文件,形如sort filename > newfile。
但是,如果你想把排序结果输出到原文件中,用重定向可就不行了。
[rocrocket@rocrocket programming]$ sort -r number.txt > number.txt
[rocrocket@rocrocket programming]$ cat number.txt
[rocrocket@rocrocket programming]$
看,竟然将number清空了。
就在这个时候,-o选项出现了,它成功的解决了这个问题,让你放心的将结果写入原文件。这或许也是-o比重定向的唯一优势所在。
[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort -r number.txt -o number.txt
[rocrocket@rocrocket programming]$ cat number.txt
5
4
3
2
1
5 sort的-n选项
你有没有遇到过10比2小的情况。我反正遇到过。出现这种情况是由于排序程序将这些数字按字符来排序了,排序程序会先比较1和2,显然1小,所以就将10放在2前面喽。这也是sort的一贯作风。
我们如果想改变这种现状,就要使用-n选项,来告诉sort,“要以数值来排序”!
[rocrocket@rocrocket programming]$ cat number.txt
1
10
19
11
2
5
[rocrocket@rocrocket programming]$ sort number.txt
1
10
11
19
2
5
[rocrocket@rocrocket programming]$ sort -n number.txt
1
2
5
10
11
19
6 sort的-t选项和-k选项
如果有一个文件的内容是这样:
[rocrocket@rocrocket programming]$ cat facebook.txt
banana:30:5.5
apple:10:2.5
pear:90:2.3
orange:20:3.4
这个文件有三列,列与列之间用冒号隔开了,第一列表示水果类型,第二列表示水果数量,第三列表示水果价格。
那么我想以水果数量来排序,也就是以第二列来排序,如何利用sort实现?
幸好,sort提供了-t选项,后面可以设定间隔符。(是不是想起了cut和paste的-d选项,共鸣~~)
指定了间隔符之后,就可以用-k来指定列数了。
[rocrocket@rocrocket programming]$ sort -n -k 2 -t : facebook.txt
apple:10:2.5
orange:20:3.4
banana:30:5.5
pear:90:2.3
我们使用冒号作为间隔符,并针对第二列来进行数值升序排序,结果很令人满意。
7 其他的sort常用选项
-f会将小写字母都转换为大写字母来进行比较,亦即忽略大小写
-c会检查文件是否已排好序,如果乱序,则输出第一个乱序的行的相关信息,最后返回1
-C会检查文件是否已排好序,如果乱序,不输出内容,仅返回1
-M会以月份来排序,比如JAN小于FEB等等
-b会忽略每一行前面的所有空白部分,从第一个可见字符开始比较。
有时候学习脚本,你会发现sort命令后面跟了一堆类似-k1,2,或者-k1.2 -k3.4的东东,有些匪夷所思。今天,我们就来搞定它—-k选项!
1 准备素材
$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
第一个域是公司名称,第二个域是公司人数,第三个域是员工平均工资。(除了公司名称,其他的别信,都瞎写的^_^)
2 我想让这个文件按公司的字母顺序排序,也就是按第一个域进行排序:(这个facebook.txt文件有三个域)
$ sort -t ‘ ‘ -k 1 facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500
看到了吧,就直接用-k 1设定就可以了。(其实此处并不严格,稍后你就会知道)
3 我想让facebook.txt按照公司人数排序
$ sort -n -t ‘ ‘ -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
不用解释,我相信你能懂。
但是,此处出现了问题,那就是baidu和sohu的公司人数相同,都是100人,这个时候怎么办呢?按照默认规矩,是从第一个域开始进行升序排序,因此baidu排在了sohu前面。
4 我想让facebook.txt按照公司人数排序 ,人数相同的按照员工平均工资升序排序:
$ sort -n -t ‘ ‘ -k 2 -k 3 facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
看,我们加了一个-k2 -k3就解决了问题。对滴,sort支持这种设定,就是说设定域排序的优先级,先以第2个域进行排序,如果相同,再以第3个域进行排序。(如果你愿意,可以一直这么写下去,设定很多个排序优先级)
5 我想让facebook.txt按照员工工资降序排序,如果员工人数相同的,则按照公司人数升序排序:(这个有点难度喽)
$ sort -n -t ‘ ‘ -k 3r -k 2 facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
此处有使用了一些小技巧,你仔细看看,在-k 3后面偷偷加上了一个小写字母r。你想想,再结合我们上一篇文章,能得到答案么?揭晓:r和-r选项的作用是一样的,就是表示逆序。因为sort默认是按照升序排序的,所以此处需要加上r表示第三个域(员工平均工资)是按照降序排序。此处你还可以加上n,就表示对这个域进行排序时,要按照数值大小进行排序,举个例子吧:
$ sort -t ‘ ‘ -k 3nr -k 2n facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
看,我们去掉了最前面的-n选项,而是将它加入到了每一个-k选项中了。
6 -k选项的具体语法格式
要继续往下深入的话,就不得不来点理论知识。你需要了解-k选项的语法格式,如下:
[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]
这个语法格式可以被其中的逗号(“,”)分为两大部分,Start部分和End部分。
先给你灌输一个思想,那就是“如果不设定End部分,那么就认为End被设定为行尾”。这个概念很重要的,但往往你不会重视它。
Start部分也由三部分组成,其中的Modifier部分就是我们之前说过的类似n和r的选项部分。我们重点说说Start部分的FStart和C.Start。
C.Start也是可以省略的,省略的话就表示从本域的开头部分开始。之前例子中的-k 2和-k 3就是省略了C.Start的例子喽。
FStart.CStart,其中FStart就是表示使用的域,而CStart则表示在FStart域中从第几个字符开始算“排序首字符”。
同理,在End部分中,你可以设定FEnd.CEnd,如果你省略.CEnd,则表示结尾到“域尾”,即本域的最后一个字符。或者,如果你将CEnd设定为0(零),也是表示结尾到“域尾”。
7 突发奇想,从公司英文名称的第二个字母开始进行排序:
$ sort -t ‘ ‘ -k 1.2 facebook.txt
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
看,我们使用了-k 1.2,这就表示对第一个域的第二个字符开始到本域的最后一个字符为止的字符串进行排序。你会发现baidu因为第二个字母是a而名列榜首。sohu和 google第二个字符都是o,但sohu的h在google的o前面,所以两者分别排在第二和第三。guge只能屈居第四了。
8 又突发奇想,,只针对公司英文名称的第二个字母进行排序,如果相同的按照员工工资进行降序排序:
$ sort -t ‘ ‘ -k 1.2,1.2 -k 3,3nr facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
由于只对第二个字母进行排序,所以我们使用了-k 1.2,1.2的表示方式,表示我们“只”对第二个字母进行排序。(如果你问“我使用-k 1.2怎么不行?”,当然不行,因为你省略了End部分,这就意味着你将对从第二个字母起到本域最后一个字符为止的字符串进行排序)。对于员工工资进行排 序,我们也使用了-k 3,3,这是最准确的表述,表示我们“只”对本域进行排序,因为如果你省略了后面的3,就变成了我们“对第3个域开始到最后一个域位置的内容进行排序” 了。
9 在modifier部分还可以用到哪些选项?
可以用到b、d、f、i、n 或 r。
其中n和r你肯定已经很熟悉了。
b表示忽略本域的签到空白符号。
d表示对本域按照字典顺序排序(即,只考虑空白和字母)。
f表示对本域忽略大小写进行排序。
i表示忽略“不可打印字符”,只针对可打印字符进行排序。(有些ASCII就是不可打印字符,比如\a是报警,\b是退格,\n是换行,\r是回车等等)
10 思考思考关于-k和-u联合使用的例子:
$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
这是最原始的facebook.txt文件。
$ sort -n -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
$ sort -n -k 2 -u facebook.txt
guge 50 3000
baidu 100 5000
google 110 5000
当设定以公司员工域进行数值排序,然后加-u后,sohu一行就被删除了!原来-u只识别用-k设定的域,发现相同,就将后续相同的行都删除。
$ sort -k 1 -u facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500
$ sort -k 1.1,1.1 -u facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
这个例子也同理,开头字符是g的guge就没有幸免于难。
$ sort -n -k 2 -k 3 -u facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
咦!这里设置了两层排序优先级的情况下,使用-u就没有删除任何行。原来-u是会权衡所有-k选项,将都相同的才会删除,只要其中有一级不同都不会轻易删除的:)(不信,你可以自己加一行sina 100 4500试试看)
11 最诡异的排序:
$ sort -n -k 2.2,3.1 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
以第二个域的第二个字符开始到第三个域的第一个字符结束的部分进行排序。
第一行,会提取0 3,第二行提取00 5,第三行提取00 4,第四行提取10 5。
又因为sort认为0小于00小于000小于0000….
因此0 3肯定是在第一个。10 5肯定是在最后一个。但为什么00 5却在00 4前面呢?(你可以自己做实验思考一下。)
答案揭晓:原来“跨域的设定是个假象”,sort只会比较第二个域的第二个字符到第二个域的最后一个字符的部分,而不会把第三个域的开头字符纳入比较范围。当发现00和00相同时,sort就会自动比较第一个域去了。当然baidu在sohu前面了。用一个范例即可证实:
$ sort -n -k 2.2,3.1 -k 1,1r facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
12 有时候在sort命令后会看到+1 -2这些符号,这是什么东东?
关于这种语法,最新的sort是这么进行解释的:
On older systems, `sort’ supports an obsolete origin-zero syntax `+POS1 [-POS2]‘ for specifying sort keys. POSIX 1003.1-2001 (*note Standards conformance::) does not allow this; use `-k’ instead.
diff:比较两个文件的不同
1)diff的传统格式输出.
############################################
cat before.txt
输出:
This is a line to be deleted
This is a line that will be changed
This is a line that will be unchanged
cat after.txt
输出:
This is a line that has been changed
This is a line that will be unchanged
This is a line that has been added
############################################
diff before.txt after.txt
输 出:
1,2c1
< This is a line to be deleted
< This is a line that will be changed
---
> This is a line that has been changed
3a3
> This is a line that has been added
############################################
注释:
传统格式的输出
1,2c1是指替换第1个文件的第1,2行到第2个文件的第2行,这里的1,2是指第1个文件的第1,2行,c是替换的意思,最后的1是第2个文件的第1行
<号是指第1个文件更改或删除的行
---号是分割两个文件
>号是第2个文件中增加或删除的行
3a3是指将第2个文件的第3行插入到第一个文件的第3行
也就是说第1个文件的:
< This is a line to be deleted
< This is a line that will be changed
被替换成第2个文件的:
> This is a line that has been changed
由于第1个文件的第3行和第2个文件的第2行一致,所以不做修改.
由于第2个文件的第3行是第1个文件所不具有的,所以在第1个文件的最后一行增加:
> This is a line that has been added
2)patch命令的应用
用diff的传统格式输出:
#################################
diff before.txt after.txt >mypatch.txt
#################################
用patch修补before.txt文件,使before.txt和after.txt一致.
#################################
cat mypatch.txt |patch before.txt
输出:
patching file before.txt
#################################
比较两个文件,现在是一致的了.
#################################
cmp before.txt after.txt
#################################
用patch命令恢复before.txt.
#################################
patch -R before.txt <mypatch.txt
输出:
patching file before.txt
#################################
注:-R标记告诉patch在反向上应用区别或者撤销patch.
再比较两个文件,现在不一致了.
#################################
cmp before.txt after.txt
输出:
before.txt after.txt differ: byte 17, line 1
#################################
3)diff的统一格式输出.
#################################
diff -u before.txt after.txt |tee mypatch.diff
输出:
--- before.txt 2009-06-20 05:21:49.000000000 +0800
+++ after.txt 2009-06-20 04:03:16.000000000 +0800
@@ -1,3 +1,3 @@
-This is a line to be deleted
-This is a line that will be changed
+This is a line that has been changed
This is a line that will be unchanged
+This is a line that has been added
#################################
注释:
diff -u选项是统一格式输出.
--- before.txt 2009-06-20 05:21:49.000000000 +0800
--- before.txt是指旧文件
+++ after.txt 2009-06-20 04:03:16.000000000 +0800
+++ after.txt是指新文件.
@@ -1,3 +1,3 @@
@@ -1,3是指第1个文件一共有3行,+1,3 @@是指第2个文件一共有3行.
-This is a line to be deleted
-This is a line that will be changed
是被删除的行
+This is a line that has been changed
是增加的行
This is a line that will be unchanged
没有-号和+号是指该行不变,因为after.txt和before.txt都有这行.
+This is a line that has been added
是增加的行
diff的统一格式比较与输出是按顺序进行的.
4)diff命令在目录中的应用.
新建old和new目录,old目录包含了初始内容,new目录包含文件的最新版本.
##########################################
mkdir old new
echo "This is one. It's unchanged." | tee old/one new/one
echo "This is two. It will change." > old/two
echo "This is two. It changed.">new/two
echo "This is three. It's new" > new/three
##########################################
创建修补文件
##########################################
diff -Nur old/ new/ >mypatch.diff
##########################################
注:-r选项按照文件目录递归创建修补文件.
-u还是统一模式
-N是指当diff遇到一个只存在于两个树中的一个树中的文件时,默认情况下跳过文件并且打印一个警告到stderr.
这个行为可以通过-N选项来更改,这也导致了diff认为丢失的文件实际上是存在的,但它是空的.采用这种方式,
一个修补文件可以包括已经创建的文件.然后应用修补程序创建新的文件.
##########################################
more mypatch.diff
输出:
diff -Nur old/three new/three
--- old/three 1970-01-01 08:00:00.000000000 +0800
+++ new/three 2009-06-20 06:55:34.000000000 +0800
@@ -0,0 +1 @@
+This is three. It's new
diff -Nur old/two new/two
--- old/two 2009-06-20 06:55:08.000000000 +0800
+++ new/two 2009-06-20 06:55:21.000000000 +0800
@@ -1 +1 @@
-This is two. It will change.
+This is two. It changed.
##########################################
[root@station230 tmp]# diff a b > patch.diff 比较不同并产生补丁文件
打补丁:
[root@station230 tmp]# patch a patch.diff
patching file a
[root@station230 tmp]# cat a
haha
haha
1111
2222
查找命令:
whereis which locate find
[root@station230 tmp]# whereis ls
ls: /bin/ls /usr/share/man/man1p/ls.1p.gz /usr/share/man/man1/ls.1.gz
[root@station230 tmp]# which passwd
/usr/bin/passwd
[root@station230 tmp]# which ls
alias ls='ls --color=tty'
/bin/ls
[root@station230 tmp]# whatis ls
locate:
[root@station230 tmp]# touch abcd.txt
[root@station230 tmp]# locate abcd.txt(关键字)
[root@station230 tmp]# vim /etc/updatedb.conf locate数据库配置文件
[root@station230 tmp]#
[root@station230 tmp]# locate abcd.txt
[root@station230 tmp]# updatedb 手动更新数据库
find:
#find 路径 条件 动作[-exec(-ok) rm....]
按名称:
[root@station230 tmp]# find / -name passwd
[root@station230 tmp]# find / -name *passwd*
[root@station230 tmp]# find / -name ??passwd
按大小:
[root@station230 tmp]# find /tmp/ -size 20M
/tmp/suibian1
[root@station230 tmp]# find /tmp/ -size -20M
[root@station230 tmp]# find /tmp/ -size +10M -a -size -20M
/tmp/suibian3
[root@station230 tmp]# find /tmp/ -size +10M -a -name suibian
[root@station230 tmp]# find /tmp/ -size +10M -a -name suibian3
/tmp/suibian3
根据类型查找:
[root@station230 tmp]# find /dev -type d
文件类型:
f
d
c
b
s
l
p
[root@station230 tmp]# find /tmp ! \( -type d -a -name .\* \)
按时间:
[root@station230 tmp]# find /tmp -amin -3
[root@station230 tmp]# atime
[root@station230 tmp]# ctime
[root@station230 tmp]# mtime
[root@station230 tmp]# 后面跟天数
[root@station230 tmp]# amin
[root@station230 tmp]# cmin
[root@station230 tmp]# mmin
[root@station230 tmp]# 后面跟分钟
按权限:
[root@station230 b]# find /b -perm 544
/b/a
按链接(硬链接)个数:
[root@station230 b]# find -links 4
./e
./f
./a
./d
#ln -s a b 软链接 重新创建一个新的inod
#ln a c 硬链接 不重新创建
inod真正存储文件信息
按用户和组:
[root@station230 b]# find -user user1
[root@station230 b]# find -group root
查找完了之后作些其他的动作:-exec -0k(会询问)
[root@station230 b]# find -user user1 -exec file {} \;
[root@station230 b]# find -name b -ok rm {} \;
< rm ... ./b > ?
[root@station230 b]# find -name b
./b
[root@station230 b]# find -name b | xargs rm
[root@station230 b]# ls