一、cut命令
1,cut命令是对行来截取的命令。先来看man中cut命令参数
-b, --bytes=LIST select only these bytes -c, --characters=LIST select only these characters -d, --delimiter=DELIM use DELIM instead of TAB forfield delimiter -f, --fields=LIST select only these fields; also print any line that contains nodelimiter character, unless the -s option is specified -n with -b: don’t splitmultibyte characters --complement complement the set of selectedbytes, characters or fields -s, --only-delimited do not print lines not containingdelimiters --output-delimiter=STRING use STRING as the output delimiterthe default is to use the input delimiter
2,参数解释
-b:以字节为单位来分割。这些字节忽略多字节边界,除非指定-n。何为多字节?比如说中
文字符,一个中文占两个字节(编码不同,可能为2-4个字节)。
-n:仅跟-b一起使用,表示取消分割多字节符。
例:
[root@localhost test2]# more test.txt abc 123 ijk mnq [root@localhost test2]# cut -b 1 test.txt a 1 i m [root@localhost test2]# more test2.txt #我这是ut-f8编码,一个中文占3个字节 123456789 中文字符 一二三 #不加-n参数表示只打印第6个字节,所以中文无法打印 [root@localhost test2]# cut -b 6 test2.txt 6 #取消分割,只要第6个自己包含在即打印 [root@localhost test2]# cut -nb 6 test2.txt 6 文 二 [root@localhost test2]# cut -nb 4 test2.txt#第4个字节未完全包含单个字符,故没有打印中文 4
-c:以字符位为单位进行分割。当一个字符占一个字节时与-b效果相同,但对于多字节字符就不同。
例:
[root@localhost test2]# cut -b 3 test.txt c 3 k q [root@localhost test2]# cut -c 3 test.txt c 3 k q [root@localhost test2]# cut -b 3 test2.txt 3 [root@localhost test2]# cut -c 3 test2.txt 3 字 三
-d:自定义分割符,默认为制表符。
-f:即fields(域),因为-f以分割符来分割的,故一般与-d一起使用。因为-f可以指定以指定
的字符进行分割,使用比较灵活,故-f与-d是常用参数。
如passw文件以“:”冒号分隔每个字段。 [root@localhost test2]# 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 #只将以“:”分隔后的第5列打印出来 [root@localhost test2]# cat/etc/passwd|head -n 5 |cut -d : -f 5 root bin daemon adm lp
-s:表示打印没有分割符的行。假设某文件行以“-”分割,若某行没有“-”符号则不打印
[root@localhost test2]# more test6.txt 1-2-3-4 a,b,c,d e-f-g-h h:i:j:k i-ii-iii-iv-v [root@localhost test2]# cut -d '-' -f 1-test6.txt 1-2-3-4 a,b,c,d e-f-g-h h:i:j:k i-ii-iii-iv-v [root@localhost test2]# cut -d '-' -f 1- -stest6.txt 1-2-3-4 e-f-g-h i-ii-iii-iv-v
可以看到-f根据指定字符分割后分成一个一个域,然后可以选择需要的域。
之前我们例子都是选择分割后的一个字节、字符或域,其实cut还支持同时打印多字符,以几个例子来了解,很简单不做多解释。
[root@localhost test2]# cat test.txt abc 123 ijk mnq [root@localhost test2]# cat test2.txt 123456789 中文字符 一二三 [root@localhost test2]# cut -b 1,3 test.txt#第1和第3域 ac 13 ik mq #第1至第3域,还可以-2表示1-2,2-表示第2域到最后。注意分割后从1开始的。 [root@localhost test2]# cut -c 1-3test2.txt 123 中文字 一二三 [root@localhost test2]# ll |cut -d ' ' -f1,10|sed '1d' #只查看权限效果 -rw-r--r--. test2.txt -rw-r--r--. test3.txt -rw-r--r--. test.txt
刚才我们说了-d选项默认是以制表符来分割的,但有些文件即有制表符符又有空格会怎么样?
[root@localhost test2]# more test3.txt id 姓名 年龄 001 张三 18 002 李四 19 003 王五 20 [root@localhost test2]# cut -d ' ' -f 2-3test3.txt id 姓名 年龄 001 张三 18 [root@localhost test2]# cut -f 2-3test3.txt 姓名 年龄 张三 18 002 李四 19 王五 20
我们发现两次效果均不是想要的结果,其实我想要结果是显示姓名和年龄。我们来看看文件真正存储形式就知道为什么是这样的结果了。
[root@localhost test2]# sed -n l test3.txt id\t\345\247\223\345\220\215\t\345\271\264\351\276\204$ 001\t\345\274\240\344\270\211\t18$ 002 \346\235\216\345\233\233 19$ 003\t\347\216\213\344\272\224 20$
可以看到第一行、第二行是通过制表符(\t)来链接的,而第三行是通过空格来隔开的,第四行即有制表符又有空格。
第一种情况,以空格分割,第一、二行没有空格所以根本就没分割。第三行分割成很多块,打印2-3块,即依然还是空格。第四行也是一样,注意中间有多个空格。
第二种情况,以制表符分割,第一、二行能够按预期打印,第三行没有制表符即没有分割所以打印全部,第四行分割成2块,所以打印2-3块的话就打印后面的全部。
对空格分割处理:
[root@localhosttest2]# more test5.txt 1 3 1 4 1 5 1 6 [root@localhosttest2]# cut -d ' ' -f 2 test5.txt 3 [root@localhost test2]#cut -d ' ' -f 3 test5.txt 4 [root@localhosttest2]# cut -d ' ' -f 4 test5.txt 5 [root@localhosttest2]# cut -d ' ' -f 5 test5.txt 6
可以这么理解每个分割符就是假设有个斜杠,但是并不打印出来,斜杠之间可能为空。
这个想象中的“斜杠”也可以打印出来,还可以自定义以某个字符串来代替。使用--output-delimiter=STRING来实现。
[root@localhosttest2]# cut -d '-' -f 1- -s test6.txt --output-delimiter='$' 1$2$3$4 e$f$g$h i$ii$iii$iv$v
即将原有的分割符替换为新的分割符。
我们也看到cut对空格处理不是那么理想化,参数较少,记住就行。