目录
wc,cut,sort,uniq,tr,paste,split
1、文本统计:wc
wc [OPTION]... [FILE]...
不指定选项默认:输出每个指定文件的行数、单词数和字节数,如果指定了多于一个文件,继续给出所有相关数据的总计。如果没有指定文件,或者文件为"-",则从标准输入读取数据。
-l, --lines 输出行数统计
-w, --words 统计单词数
-c, --bytes输出字节数统计
-m, --chars输出字符数统计
[root@Node3 src]# cat test1 aaa bbb ccc #空格和换行符也都算1个字符 hello world 你好,世界 #中文1个算多个字符,没有中文时,字符数等于字节数 [root@Node3 src]# wc test1 4 6 43 test1 [root@Node3 src]# wc -l test1 4 test1 [root@Node3 src]# wc -m test1 33 test1 [root@Node3 src]# wc -c test1 43 test1 [root@Node3 src]# wc test1 3 4 25 test1 [root@Node3 src]# wc -l test1 3 test1 [root@Node3 src]# wc -w test1 4 test1 [root@Node3 src]# wc -c test1 25 test1 [root@Node3 src]# wc -m test1 25 test1
2、字符截取:cut
从每个文件中输出指定部分到标准输出,它每次处理的对象是“一行”文本,从中选取出用户所需要的部分,返回的是列。默认以空格为分隔符,也可以指定特定的分隔符,然后打印出以分隔符隔开的集体某一列或某几列。
cut [OPTION] ... [FILE]..
-d:--delimiter=分界符 使用指定分界符代替制表符作为区域分界
-d ' ' :表示以空格为分隔符 #默认以制表符为分割符
-f #:指明要保留的字段(列)
单个: #
离散的多个:#,#,#
连续的多个:#-#
-s, --only-delimited 不打印没有包含分界符的行
[root@Node3 src]# cut -f 1 test1 aaa bbb ccc hello,world [root@Node3 src]# cut -d '' -f 1 test1 aaa bbb ccc hello,world [root@Node3 src]# cut -d ' ' -f 1 test1 aaa hello,world [root@Node3 src]# cut -s -d ' ' -f 1 test1 aaa [root@Node3 src]# cut -d ' ' -f 2 test1 bbb hello,world [root@Node3 src]# cut -d ' ' -f 3 test1 ccc hello,world [root@Node3 src]# cut -d ' ' -f 4 test1 hello,world [root@Node3 src]# cut -d ' ' -f 1,3 test1 #保留第一和第三列 aaa ccc hello,world [root@Node3 src]# cut -d ' ' -f 1-3 test1 #保留第一到第三列 aaa bbb ccc hello,world [root@Node3 src]# cat test2 a b c d e #一个tab键是制表符,c和d之间是1个空格,d和e之间2个空格 1 2 3 4 5 [root@Node3 src]# cut -f 1 test2 #默认以制表符为分隔符 a 1 [root@Node3 src]# cut -f 3 test2 #制表符和空格有区别 c d e 3 4 5 [root@Node3 src]# cut -d '' -f 3 test2 #引号之间不能没有空格 a b c d e 1 2 3 4 5 [root@Node3 src]# cut -d ' ' -f 1 test2 #再次说明制表符不等于4个空格 a b c 1 2 3 [root@Node3 src]# cut -d ' ' -f 1 test2 #不能以2个空格作为分隔符,必须是单个字符 cut: 分界符必须是单个字符 请尝试执行"cut --help"来获取更多信息。 [root@Node3 src]# cut -d ' ' -f 2 test2 d 4 [root@Node3 src]# cut -d ' ' -f 3 test2 #有多个空格时,以1个空格为分隔符后的列还是1个空格,所有分隔符是多个空格时,使用cut可能会有问题 [root@Node3 src]# cut -d ":" -f 1,6-7 /etc/passwd #以“:”为分隔符 root:/root:/bin/bash bin:/bin:/sbin/nologin daemon:/sbin:/sbin/nologin [root@Node3 src]# cut -d ' ' -f 4 test2 #下一列 e 5 [root@Node3 src]# echo "1aa2aa3"|cut -d 'a' -f 1 1 [root@Node3 src]# echo "1aa2aa3"|cut -d 'a' -f 2 [root@Node3 src]# echo "1aa2aa3"|cut -d 'a' -f 3 2
以上cut使用场景是在处理的行中有特定的分隔符的时候,但是如果要处理的行是没有分隔符的,那cut就没有用了吗?
cut还可以打印指定个数的字符或字节,这个时候cut的用法如下:
[root@Node3 src]# cut -b 5 test1 b o [root@Node3 src]# cut -b 5 test1 test2 b o c 3 [root@Node3 src]# cut -b 5-10 test1 test2 bbb cc o,worl c d e 3 4 5 [root@Node3 src]# cut -c 5-10 test1 test2 bbb cc o,worl c d e 3 4 5 [root@Node3 src]# cut -c 5-100 test1 test2 bbb ccc o,world c d e 3 4 5
3、文本排序:sort
串联排序所有指定文件并将结果写到标准输出
注意:这里说的排序是行的上,下排序;针对的行不是列
sort [OPTION]... [FILE]...
-r:逆序排序
-f:忽略大小写 常与-u结合使用
-n:按数值大小排序
-t:指定分隔符,默认是空格
-k:按照指定的字段范围
-u:移除重复的行
sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。
1 )准备素材
[root@Node3 src]# cat facebook.txt google 110 5000 baidu 100 5000 gab 200 200 guge 50 3000 sohu 100 4500 [root@Node3 src]# sort facebook.txt baidu 100 5000 gab 200 200 google 110 5000 guge 50 3000 sohu 100 4500 [root@Node3 src]# sort -n facebook.txt baidu 100 5000 gab 200 200 google 110 5000 guge 50 3000 sohu 100 4500 [root@Node3 src]# sort -r facebook.txt sohu 100 4500 guge 50 3000 google 110 5000 gab 200 200 baidu 100 5000
第一个域是公司名称,第二个域是公司人数,第三个域是员工平均工资。
2 )我想让facebook.txt按照公司人数排序
[root@Node3 src]# sort -t ' ' -k 2 -n facebook.txt guge 50 3000 baidu 100 5000 sohu 100 4500 google 110 5000 gab 200 200
但是,此处出现了问题,那就是baidu和sohu的公司人数相同,都是100人,这个时候怎么办呢?
按照默认规矩,是从第一个域开始进行升序排序,因此baidu排在了sohu前面。
但是这里如果不加-n:
[root@Node3 src]# sort -t ' ' -k 2 facebook.txt sohu 100 4500 baidu 100 5000 google 110 5000 gab 200 200 guge 50 3000
3 )我想让facebook.txt按照公司人数排序 ,人数相同的按照员工平均工资升序排序:
[root@Node3 src]# sort -n -t ' ' -k 2 -k 3 facebook.txt guge 50 3000 sohu 100 4500 baidu 100 5000 google 110 5000 gab 200 200
看,我们加了一个-k2 -k3就解决了问题。对滴,sort支持这种设定,就是说设定域排序的优先级,先以第2个域进行排序,如果相同,再以第3个域进行排序
[root@Node3 src]# sort -n -t ' ' -k 2 -k 1 facebook.txt guge 50 3000 baidu 100 5000 sohu 100 4500 google 110 5000 gab 200 200
4 )我想让facebook.txt按照员工工资降序排序,如果员工人数相同的,则按照公司人数升序排序
[root@Node3 src]# sort -n -t ' ' -k 3 -r -k 2 facebook.txt google 110 5000 baidu 100 5000 sohu 100 4500 guge 50 3000 gab 200 200 [root@Node3 src]# sort -n -t ' ' -k 3r -k 2 facebook.txt #r和区域写在一起 baidu 100 5000 google 110 5000 sohu 100 4500 guge 50 3000 gab 200 200
5 )-k选项的具体语法格式
要继续往下深入的话,就不得不来点理论知识。你需要了解-k选项的语法格式,如下:
[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]
这个语法格式可以被其中的逗号(“,”)分为两大部分,Start部分和End部分,注意: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(零),也是表示结尾到“域尾”。
6)从公司英文名称的第二个字母开始进行排序:
[root@Node3 src]# cat facebook.txt google 110 5000 baidu 100 5000 gab 200 200 guge 50 3000 sohu 100 4500 [root@Node3 src]# sort -t ' ' -k 1.2 facebook.txt gab 200 200 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只能屈居第四了。
[root@xxj tmp]# sort -t' ' -k1.2 555test faidu 100 5000 cb aa 30 c bb aa 30 x ab ba 30 b sohu 100 4500 eoogle 100 6000 guge 50 3000 [root@xxj tmp]# sort -nt' ' -k1.2 555test ab ba 30 b bb aa 30 x cb aa 30 c eoogle 100 6000 faidu 100 5000 guge 50 3000 sohu 100 4500 [root@xxj tmp]#
只针对公司英文名称的第二个字母进行排序,如果相同的按照员工工资进行降序排序:
[root@Node3 src]# sort -t ' ' -k 1.2,1.2 -k 3,3nr facebook.txt baidu 100 5000 gab 200 200 google 110 5000 sohu 100 4500 guge 50 3000
由于只对第二个字母进行排序,所以我们使用了-k 1.2,1.2的表示方式,表示我们“只”对第二个字母进行排序。(如果你问“我使用-k 1.2怎么不行?”,当然不行,因为你省略了End部分,这就意味着你将对从第二个字母起到本域最后一个字符为止的字符串进行排序)。对于员工工资进行排 序,我们也使用了-k 3,3,这是最准确的表述,表示我们“只”对本域进行排序,因为如果你省略了后面的3,就变成了我们“对第3个域开始到最后一个域位置的内容进行排序” 了。
4、去重复行:uniq
uniq [选项]... [文件]
说明:这个命令读取输入文件,并比较相邻的行,删除相同且相邻的的重复行
-i:忽略大小写
-d:仅显示重复的行
-u:仅显示不重复的行
-c:去重后显示每行出现了的次数(相同且相邻才是重复)
[root@Node3 src]# cat uniq.txt abc 123 123 abc ABC 123 [root@Node3 src]# uniq uniq.txt abc 123 abc ABC 123 [root@Node3 src]# uniq -i uniq.txt abc 123 abc 123 [root@Node3 src]# uniq -d uniq.txt 123 [root@Node3 src]# uniq -di uniq.txt 123 abc [root@Node3 src]# uniq -u uniq.txt abc abc ABC 123 [root@Node3 src]# uniq -c uniq.txt 1 abc 2 123 1 abc 1 ABC 1 123
因为uniq是删除去除连续相同的行,所有uniq一般和sort命令一起使用,也就是先将文件使用sort排序(这样重复的内容就能显示在连续的几行中),然后再使用uniq删除掉重复的行
[root@Node3 src]# sort uniq.txt|uniq -c 3 123 2 abc 1 ABC
5、文本替换:tr
tr [OPTION]... SET1 [SET2] #后面不能带参数
把输出数据中的在SET1中的每个字符对应地替换为SET2的每个字符
-d, --delete 删除匹配SET1的内容,并不作替换
[root@localhost ~]# cat /etc/issue CentOS release 6.5 (Final) Kernel \r on an \m [root@localhost ~]# tr 'aen' 'x' </etc/issue #不会对原文件的内容有影响 CxxtOS rxlxxsx 6.5 (Fixxl) Kxrxxl \r ox xx \m [root@localhost ~]# tr 'aen' 'xxx' </etc/issue #逐字符,不是单词 CxxtOS rxlxxsx 6.5 (Fixxl) Kxrxxl \r ox xx \m [root@Node3 src]# echo "xiejun"|tr [xj] [JX] JieXun [root@Node3 src]# echo "xiejun"|tr xj JX JieXun [root@localhost ~]# tr 'aen' 'xyz' </etc/issue CyztOS rylyxsy 6.5 (Fizxl) Kyrzyl \r oz xz \m [root@localhost ~]# tr 'aen' '' </etc/issue tr: 当不截断设置1 时,字符串2 不能为空 [root@localhost ~]# tr 'aen' ' ' </etc/issue C tOS r l s 6.5 (Fi l) K r l \r o \m [root@localhost ~]# tr 'aen' </etc/issue tr: "aen" 后缺少操作数 当进行替换操作时必须给定两组字符串。 请尝试执行"tr --help"来获取更多信息。 root@localhost ~]# tr -d [ae] </etc/issue CntOS rls 6.5 (Finl) Krnl \r on n \m
6、文本合并:paste
paste的作用在于将文件按照行进行合并,中间使用tab隔开
-d:指定在合并文件时行间的分隔符,默认是制表符
-s, --serial 不使用平行的行目输出模式,而是每个文件占用一行
[root@Node3 src]# cat a 1 1 2 2 [root@Node3 src]# cat b a a b b [root@Node3 src]# paste a b 1 1 a a 2 2 b b [root@Node3 src]# paste -s a b 1 1 2 2 a a b b [root@Node3 src]# paste b a a a 1 1 b b 2 2 [root@Node3 src]# paste -d ':' a b 1 1:a a 2 2:b b [root@Node3 src]# paste -s -d : a b 1 1:2 2 a a:b b [root@Node3 src]# cat 1.txt 1 10 11 1000 19 a ab A b z 2 5 [root@Node3 src]# cat 1.txt |paste -s 1 10 11 1000 19 a ab A b z 2 5 [root@Node3 src]# cat 1.txt |paste -s -d : 1:10:11:1000:19:a:ab:A:b:z:2:5 [root@Node3 src]# cat 1.txt |paste -s -d ' ' 1 10 11 1000 19 a ab A b z 2 5 [root@Node3 src]# paste a b 1.txt 1 1 a a 1 2 2 b b 10 11 1000 19 a ab A b z 2 5 [root@Node3 src]# paste -s a b 1.txt 1 1 2 2 a a b b 1 10 11 1000 19 a ab A b z 2 5 [root@Node3 src]#
7、分割文件:split
实现文件分割
支持按照行数分割和按照大小分割两种模式
-l:按行分割
-h:按大小分割,
注意:二进制文件没有行的概念,只能按大小进行分割
[root@Node3 src]# cp /etc/passwd . [root@Node3 src]# cat -n passwd 1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6 sync:x:5:0:sync:/sbin:/bin/sync 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8 halt:x:7:0:halt:/sbin:/sbin/halt 9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin 11 operator:x:11:0:operator:/root:/sbin/nologin 12 games:x:12:100:games:/usr/games:/sbin/nologin 13 gopher:x:13:30:gopher:/var/gopher:/sbin/nologin 14 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 15 nobody:x:99:99:Nobody:/:/sbin/nologin 16 dbus:x:81:81:System message bus:/:/sbin/nologin 17 vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin 18 saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin 19 postfix:x:89:89::/var/spool/postfix:/sbin/nologin 20 haldaemon:x:68:68:HAL daemon:/:/sbin/nologin 21 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin [root@Node3 src]# split -l 10 passwd passwd_ [root@Node3 src]# ls 1.txt a c passwd passwd_ab sort.txt test2 2.txt b facebook.txt passwd_aa passwd_ac test1 uniq.txt
分隔完成后会生成多个以passwd_开头为文件名的小文件
[root@Node3 src]# cat -n passwd_* 1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6 sync:x:5:0:sync:/sbin:/bin/sync 7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 8 halt:x:7:0:halt:/sbin:/sbin/halt 9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 10 uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin 11 operator:x:11:0:operator:/root:/sbin/nologin 12 games:x:12:100:games:/usr/games:/sbin/nologin 13 gopher:x:13:30:gopher:/var/gopher:/sbin/nologin 14 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 15 nobody:x:99:99:Nobody:/:/sbin/nologin 16 dbus:x:81:81:System message bus:/:/sbin/nologin 17 vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin 18 saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin 19 postfix:x:89:89::/var/spool/postfix:/sbin/nologin 20 haldaemon:x:68:68:HAL daemon:/:/sbin/nologin 21 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin [root@Node3 ~]# ls -lh mariadb-10.1.16-linux-x86_64.tar.gz -rw-r--r-- 1 root root 332M 11月 18 17:45 mariadb-10.1.16-linux-x86_64.tar.gz [root@Node3 ~]# split -b 100M mariadb-10.1.16-linux-x86_64.tar.gz mariadb_ [root@Node3 ~]# ls -lh mariadb_* -rw-r--r-- 1 root root 100M 11月 26 15:11 mariadb_aa -rw-r--r-- 1 root root 100M 11月 26 15:11 mariadb_ab -rw-r--r-- 1 root root 100M 11月 26 15:11 mariadb_ac -rw-r--r-- 1 root root 32M 11月 26 15:11 mariadb_ad
可以将一个大文件分割成很多个小文件,有时需要将文件分割成更小的片段,比如为提高可读性,生成日志
语法
split(选项)(file)PREFIX
选项
-b:值为每一输出档案的大小,单位默认为 -C:每一输出档中,单行的最大 --l:值为每一输出档的列数大小。 PREFIX:代表前导符,可作为切割后文件名的前导符。
实例
生成一个大小为100KB的测试文件:
dd if=/dev/zero bs=100k count=1 of=date.file
结果:
1+0 records in
1+0 records out
102400 bytes (102 kB) copied, 0.00043 seconds, 238 MB/s
使用split命令将上面创建的date.file文件分割成大小为10KB的小文件:
split -b 10k date.file
ls
结果:
date.file xaa xab xac xad xae xaf xag xah xai xaj
文件被分割成多个带有字母的后缀文件,如果想用数字后缀可使用-d参数,同时可以使用-a length来指定后缀的长度:
split -b 10k date.file -d -a 3
ls
结果:
date.file x000 x001 x002 x003 x004 x005 x006 x007 x008 x009
为分割后的文件指定文件名的前缀:
split -b 10k date.file -d -a 3 split_file
ls
结果:
date.file split_file000 split_file001 split_file002 split_file003 split_file004 split_file005 split_file006 split_file007 split_file008 split_file009
使用-l选项根据文件的行数来分割文件,例如把文件分割成每个包含10行的小文件:
split -l 10 date.file
PS
cat x*>>y*
将split分割的文件合并成一个