linux剪切一行,Linux基础命令:文本处理工具之cut

大纲

1、cut 介绍

2、cut实例演示

3、字符编码

文档版本更新时间备注

v12016-02-14

版本更新信息:cut 版本

cut (GNU coreutils) 8.4

一、cut介绍

Cut out selected fields of each line of a file. Cut command can be used to display only specific columns from a text file or other command outputs.

Cut 输入字符中指定的字段或指定的范围。若处理的是字段,则定界符隔开的即为各字段,而输出时字段也以给定的定界符隔开。默认的定界符为制表字符(TAB)。

我们可以通过man或者--help选项查看cut的使用帮助。[root@localhost ~]# cut --help

Usage: cut [OPTION]... [FILE]...

Print selected parts of lines from each FILE to standard output.

Mandatory arguments to long options are mandatory for short options too.

-b, --bytes=LIST      select only these bytes

-c, --characters=LIST   select only these characters

-d, --delimiter=DELIM   use DELIM instead of TAB for field delimiter

-f, --fields=LIST     select only these fields;  also print any line

that contains no delimiter character, unless

the -s option is specified

-n             with -b: don't split multibyte characters

--complement    complement the set of selected bytes, characters

or fields.

-s, --only-delimited    do not print lines not containing delimiters

--output-delimiter=STRING  use STRING as the output delimiter

the default is to use the input delimiter

--help     display this help and exit

--version  output version information and exit

Use one, and only one of -b, -c or -f.  Each LIST is made up of one

range, or many ranges separated by commas.  Selected input is written

in the same order that it is read, and is written exactly once.

Each range is one of:

N     N'th byte, character or field, counted from 1

N-    from N'th byte, character or field, to end of line

N-M   from N'th to M'th (included) byte, character or field

-M    from first to M'th (included) byte, character or field

这里列出了我们最常使用的一些选项。下面详述几个重要选项:-b list    The list following -b specifiesbyte positions(for instance, -b1-72 would pass the first 72 bytes of each line). When -b and -n are used together, list is adjusted so that no multi-byte character is split. If -b is used, the input line should contain 1023 bytes or less.

-c list    The list following -c specifiescharacter positions(for instance, -c1-72 would pass the first 72 characters of each line).

-f list    The list following -f isa list of fieldsassumed to be separated in the file by a delimiter character (see -d ); for instance, -f1,7 copies the first and seventh field only. Lines with no field delimiters will be passed through intact (useful for table subheadings), unless -s is specified. If -f is used, the input line should contain 1023 characters or less.

list      A comma-separated or blank-character-separated list of integer field numbers (in increasing order), with optional - to indicate ranges (for instance, 1,4,7;         1-3,8; -5,10(short for 1-5,10); or 3- (short for third through last field)).

-n        Do not split characters. When -b list and -n are used together, list is adjusted so that no multi-byte character is split.

-d delim   The character following -d is the field delimiter (-f option only).Default is TAB. Space or other characters with special meaning to the shell must be quoted. delim can be a multi-byte character.

-s        Suppresses lines with no delimiter characters in case of -f option. do not print lines not containing delimiters. Unless  specified, lines with no delimiters will be passed through untouched. file A path name of an input file. If no file operands are specified, or if a file operand is -, the standard input will beused.

说明:cut命令从文件的每一行剪切字节(bytes)、字符(characters)、字段(fields)并输出。cut以什么作为剪切的依据呢?

剪切依据:-b,按字节(bytes)切

-c,按字符(characters)切

-f, 按域(fields)切,通常结合 -d (delimiter)选项一起使用,默认TAB

范围表示:n          第n个字节/字符/字段

n-        从第n个字节/字符/字段到最后一个字节/字符/字段

n-m     从第n个字节/字符/字段到第m个字节/字符/字段,包括m

-m       从行的开头到第m个字节/字符/字段,包括m

二、cut实例演示

为了方便演示,我们创建一个测试文件myfile,内容如下:[yy@localhost ~]$ cat myfile

cat command for file oriented operations.

cp command for copy files or directories.

ls command to list out files and directories with its attributes.

使用 -c 选项:按字符提取

a、如果我想要从myfile中提取每一行的第2个字符(character,-c option)[yy@localhost ~]$ cut -c2 myfile

a

p

s

这里我们使用-c选项,然后接提取第几个字符。

b、提取一段范围(range)的字符(character, -c option),比如前3个字符和第5个字符[yy@localhost ~]$ cut -c1-3,5 myfile

catc

cp o

ls o

这里需要注意的是:cut命令如果使用了-b,-c或-f选项,那么执行此命令时,cut会先把后面所有的范围进行【从小到大】排序,然后再提取。所以想通过指定范围的方式来排列特定的字符[字节/域]顺序是行不通的。

如,我想把第5个字符放在1-3个字符的前面, 我们把list的顺序调整, -c5,1-3:[yy@localhost ~]$ cut -c5,1-3 myfile

catc

cp o

ls o

# 结果很明显,这样是不行滴。

## cut会先把-c后面所有的定位进行从小到大排序,然后再提取

[yy@localhost ~]$ cut -c1-3,5 myfile        # 实际上,cut会重新调整为1-3,5

c、如果我想提取第5个字符(character, -c option)之后的所有字符[yy@localhost ~]$ cut -c5- myfile

command for file oriented operations.

ommand for copy files or directories.

ommand to list out files and directories with its attributes.

d、如果我想提取从行开始到第5个字符之间的所有字符(character, -c option)[yy@localhost ~]$ cut -c-5 myfile

cat c

cp co

ls co

使用-f,-d选项:

我们知道 /etc/passwd 文件是以":"分隔的,那么我们就用它来演示,为了方便显示,只显示3行。

e、我们想从/etc/passwd中仅提取出用户名[yy@localhost ~]$ head -n3 /etc/passwd | cut -d: -f1

root

bin

daemon

我们使用-d选项来指定域分隔符(delimiter),【默认的分隔符为TAB】。然后我们用-f选项指定选择哪一个域。

f、如果我想提取shell为/bin/bash的用户的用户名和家目录字段[yy@localhost ~]$ grep 'bash' /etc/passwd | cut -d: -f1,6

root:/root

yy:/home/yy

g、同上,只是我们想提取1-4以及6,7域[yy@localhost ~]$ grep 'bash' /etc/passwd | cut -d: -f1-4,6,7

root:x:0:0:/root:/bin/bash

yy:x:500:500:/home/yy:/bin/bash

h、提取所有的域,并排除特定的域[yy@localhost ~]$ head -n3 /etc/passwd | cut -d':' --complement -f7

root:x:0:0:root:/root

bin:x:1:1:bin:/bin

daemon:x:2:2:daemon:/sbin

提取了除第7个域之外的所有域。

使用-s选项:

不打印那些没有包含指定分隔符的行,do not print lines not containing delimiters

i、如果我们指定一个不是":"的分隔符,那么cut仅仅打印整个行[yy@localhost ~]$ head -n3 /etc/passwd | cut -d'|' -f1

root:x:0:0:root:/root:/bin/bash

bin:x:1:1:bin:/bin:/sbin/nologin

daemon:x:2:2:daemon:/sbin:/sbin/nologin

如果我只想过滤和打印出包含指定分隔符的行,怎么办? 使用 -s 选项[yy@localhost ~]$ head -n3 /etc/passwd | cut -s -d'|' -f1

[yy@localhost ~]$

因为3行都没有包含"|"分隔符, 所以都没有被打印。

使用--output-delimiter改变默认的输出分隔符

j、提取/etc/passwd中的第1,6,7域,以"#"进行分隔[yy@localhost ~]$ head -n3 /etc/passwd | cut -d':' -f1,6,7 --output-delimiter='#'

root#/root#/bin/bash

bin#/bin#/sbin/nologin

daemon#/sbin#/sbin/nologin

k、指定输出分隔符为换行符(\n)

这里比较特殊,我们必须使用 $'\n'来指示使用换行符指定为'\n', --output-delimiter='\n'[yy@localhost ~]$ head -n2 /etc/passwd | cut -d':' -f1,6,7 --output-delimiter='\n'

root\n/root\n/bin/bash

bin\n/bin\n/sbin/nologin指定为 $'\n', --output-delimiter=$'\n'[yy@localhost ~]$ head -n2 /etc/passwd | cut -d':' -f1,6,7 --output-delimiter=$'\n'

root

/root

/bin/bash

bin

/bin

/sbin/nologin

关于字符(-c)和字节(-b)的讨论:

POSIX系统中,cut识别多字节字符(multibyte characters)。因此,“字符(character)” 与 “字节(byte)”意义不同。

对于使用ASCII编码的文本来说, -c和-b并没有太大的区别,但是对于多字节的情况,它们就大大的不同了。我们准备示例文件 test_cn.txt,内容如下:[yy@localhost ~]$ cat test_cn.txt

复旦大学

上海交通大学

南京大学

中国人民大学

香港科技大学

我们提取第2个字符出来[yy@localhost ~]$ cut -c2 test_cn.txt

那么,我们使用-b选项呢?[yy@localhost ~]$ cut -b2 test_cn.txt

看到了吧,上面发生了什么情况,全部都乱码显示

wail.gif。用-c则会以字符为单位,输出正常;而-b只会傻傻的以字节(8位二进制位)来计算,输出就是乱码。既然提到了这个知识点,就再补充一点。

三、什么是编码(对应的编码表)

在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a、b、c、d这样的52个字母(包括大写)、以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套规则(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了所谓的ASCII编码,统一规定了上述常用符号用哪些二进制数来表示。

ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符。所以,对于英文来说一个字符对应一个字节是没有任何问题的,一个字符8bit。但是问题是汉字编码数量庞大,字形复杂,所以只用第一个字节是没有办法表示的。 所以必须用多个字节来表示一个字符。常见的中文字符集有: GB2312-80字符集,中文名国家标准字符集, Big-5字符集,中文名大五码, GBK字符集,中文名国家标准扩展字符集。ISO/IEC 10646 / Unicode字符集,一个字符用16bit表示。

字符在计算机中的存储:

在 ASCII 阶段,单字节字符串使用一个字节存放一个字符(SBCS)。比如,"Bob123" 在内存中为:426F6231323300

Bob123\0

在使用 ANSI 编码支持多种语言阶段,每个字符使用一个字节或多个字节来表示(MBCS),因此,这种方式存放的字符也被称作多字节字符。比如,"中文123" 在中文 Windows 95 内存中为7个字节,每个汉字占2个字节,每个英文和数字字符占1个字节。D6 D0CE C43132330

中文123\0

在 UNICODE 被采用之后,计算机存放字符串时,改为存放每个字符在 UNICODE 字符集中的序号。目前计算机一般使用 2 个字节(16 位)来存放一个序号(DBCS),因此,这种方式存放的字符也被称作宽字节字符。比如,字符串 "中文123" 在 Windows 2000 下,内存中实际存放的是 5 个序号:2D 4E87 6531 0032 0033 0000 00

中文123\0

当遇到多字节字符时,可以使用-n选项,-n用于告诉cut不要将多字节字符拆开。[yy@localhost ~]$ cut -b2 test_cn.txt

上面为乱码显示。

使用-n选项[yy@localhost ~]$ cut -b2 -n test_cn.txt

什么也没有打印。它就不会去拆多字节字符了。

四、cut的不足

猜出来了吧?对,【就是在处理连续多分隔符时。】

如果文件里面的某些域是由若干个空格或其他分隔符来间隔的,那么用cut就有点麻烦了,因为cut只擅长处理“以一个字符间隔”的文本内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值