cut是一个选取命令,就是将一段数据经过分析,取出我们想要的。
(1)其语法格式为:
cut [-bn] [file]
cut [-c] [file]
cut [-df] [file]
命令解释:
cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。如果不指定 File 参数,cut 命令将读取标准输入。必须指定 -b、-c 或 -f 标志之一。一般来说,选取信息通常是针对“行”来进行分析的,并不是整篇信息分析的。
主要参数
-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
-c :以字符为单位进行分割。
-d :自定义分隔符,默认为制表符。
-f :与-d一起使用,指定显示哪个区域。
-n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的范围之内,该字符将被写出;否则,该字符将被排除。
(2)cut使用范例,怎么准确获取想要的信息:
cut命令主要是接受三个定位方法:
第一,字节(bytes),用选项-b
第二,字符(characters),用选项-c
第三,域(fields),用选项-f
(3)以“字节”定位
举个例子吧,当你执行who命令时,会输出类似如下的内容:
[05_shell]who
huibo pts/0 2014-02-28 10:01 (10.220.6.22)
huibo pts/1 2014-02-28 10:16 (172.20.223.5)
xiaojie pts/6 2014-02-28 10:18 (172.20.223.23)
delong pts/7 2014-02-28 11:14 (172.20.223.4)
xiuhai pts/8 2014-02-28 10:54 (172.20.223.22)
delong pts/9 2014-02-28 13:53 (172.20.223.4)
如果我们想提取每一行的第3个字节,就这样:
[rocrocket@rocrocket programming]$ who|cut -b 3
[05_shell] who|cut -b 3
i
i
a
l
u
l
(4)如果“字节”定位中,我想提取连续,不连续的字节例如:2-4,6,7。-b支持形如2-4的写法,而且多个定位之间用逗号隔开。
例子:
[05_shell]who|cut -b 2-4,6,7
uib
uib
iaoie
elog
iuhi
elog
注意,cut命令如果使用了-b选项,cut会先把-b后面所有的定位进行从小到大排序,然后再提取。不是按照我们书写的提前顺序去完成提取。
[05_shell]who|cut -b 6,7,2-4
uib
uib
iaoie
elog
iuhi
elog
(5)-b指定提取范围技巧
[05_shell]who
huibo pts/0 2014-02-28 10:01 (10.220.6.22)
huibo pts/1 2014-02-28 10:16 (172.20.223.5)
[05_shell]who|cut -b -2
hu
hu
提取从开始到第二个字节的所有字符.
[05_shell]who|cut -b 2-
uibo pts/0 2014-02-28 10:01 (10.220.6.22)
uibo pts/1 2014-02-28 10:16 (172.20.223.5)
iaojie pts/6 2014-02-28 10:18 (172.20.223.23)
提取从第二个字节开始到最后的所有字符.
并且都包含中间衔接的字符(第二个字符,边界字符)如果使用who|cut -b -2,2-会什么现象呢?
[05_shell]who|cut -b 2-,-2
huibo pts/0 2014-02-28 10:01 (10.220.6.22)
huibo pts/1 2014-02-28 10:16 (172.20.223.5)
输出整行。
(6)-c以字符为定位标志的的例子
提取第3,第4,第5和第8个字符:
[05_shell]who|cut -c 3-5,8
ibo
ibo
aoj
看着跟-b没有什么区别,看似相同,只是因为这个who输出的都是单字节字符,所以用-b和-c没有区别。如果提取中文,区别就看出来了
[05_shell]cat abc.text
星期一
星期二
星期三
星期四
星期五
星期六
星期天
[05_shell]cut -b 2 abc.text
�
�
�
�
[05_shell]cut -c 2 abc.text
�
�
�
�
这里也是乱码,因为utf-8使用三个自己去表示汉字,一般gb2312使用两个自己表示,这个时候需要使用一下方式表示才能正常输出:-nc (指定的字符范围)
[05_shell]cut -nc 7,8,9 abc.text
一
二
三
四
五
六
天
˜
看到了吧,用-c则会以字符为单位,输出正常;而-b只会傻傻的以字节(8位二进制位)来计算,输出就是乱码。
既然提到了这个知识点,就再补充一句,如果你学有余力,就提高一下。当遇到多字节字符时,可以使用-n选项,-n用于告诉cut不要将多字节字符拆开。
例子如上,如下:
[05_shell]cut -nb 7,8,9 abc.text
一
二
三
四
五
六
天
(7)域--其实就是不确定的分隔字段,每个字段字母长度不可预知。
刚才提到的-b和-c只能在固定格式的文档中提取信息,而对于非固定格式的信息则束手无策。这时候“域”就派上用场了。
例如这个文件/etc/passwd文件,你会发现,它并不像who的输出信息那样具有固定格式,而是比较零散的排放。
但是,冒号在这个文件的每一行中都起到了非常重要的作用,冒号用来隔开每一个项。
cut命令提供了这样的提取方式,具体的说就是设置“间隔符”,再设置“提取第几个域(字段)
以/etc/passwd的前五行内容为例:
[05_shell]cat /etc/passwd|head -n 5
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
[05_shell]cat /etc/passwd|head -n 5|cut -d : -f 1
root
daemon
bin
sys
sync
用-d来设置间隔符为冒号,然后用-f来设置我要取的是第一个域,再按回车,所有的用户名就都列出来。
当然,在设定-f时,也可以使用例如3-5或者4-类似的格式:
[05_shell]cat /etc/passwd|head -n 5|cut -d : -f 1-3,5
root:x:0:root
daemon:x:1:daemon
bin:x:2:bin
sys:x:3:sys
sync:x:4:sync
(8)如果遇到空格和制表符时,怎么分辨呢?有时候制表符确实很难辨认,有一个方法可以看出一段空格到底是由若干个空格组成的还是由一个制表符组成的。
[05_shell]cat abc.text
this is atab.
this is space
[05_shell]sed -n l abc.text
this is atab.\t$
this is space $
$
看到了吧,如果是制表符(TAB),那么会显示为\t符号,如果是空格,就会原样显示。
通过此方法即可以判断制表符和空格了。
注意,上面sed -n后面的字符是L的小写字母哦,不要看错。
(9)我应该在cut -d中用什么符号来设定制表符或空格呢?
其实cut的-d选项的默认间隔符就是制表符,所以当你就是要使用制表符的时候,完全就可以省略-d选项,而直接用-f来取域就可以了。
如果你设定一个空格为间隔符,那么就这样:
[05_shell]cut -d ' ' -f 1 abc.text
this
this
注意,两个单引号之间可确实要有一个空格哦,不能偷懒。而且,你只能在-d后面设置一个空格,可不许设置多个空格,因为cut只允许间隔符是一个字符。
(10)cut有哪些缺陷和不足?就是在处理多空格时。
如果文件里面的某些域是由若干个空格来间隔的,那么用cut就有点麻烦了,因为cut只擅长处理“以一个字符间隔”的文本内容,指定个空格会出错。
[05_shell]cut -d ' ' -f 1 abc.text
cut: the delimiter must be a single character
Try `cut --help' for more information.