shell工具-sort、uniq、paste、cut、xargs详解
原创
©著作权归作者所有:来自51CTO博客作者honeyR的原创作品,请联系作者获取转载授权,否则将追究法律责任
sort
作用:
sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较, 后将他们按升序输出。
举例如下:
[root@MiWiFi-R1CL-srv ~]# cat file
bbbbbbbb
cccccccc
dddddddd
ffffffff
cccccccc
aaaaaaaa
[root@MiWiFi-R1CL-srv ~]# sort file
aaaaaaaa
bbbbbbbb
cccccccc
cccccccc
dddddddd
ffffffff
选项
选项
| 作用
|
-r
| 以降序方式排列
|
-u
| 在输出行中去除重复行
|
-n
| 以数值来排序
|
-t
| 设定间隔符
|
-k
| 指定了间隔符之后,就可以用-k来指定列数进行排序
|
-f
| 将小写字母都转换为大写字母来进行比较,即忽略大小写
|
-c
| 会检查文件是否已排好序,如果乱序,则输出第一个乱序的行的相关信息,后返回1
|
-C
| 会检查文件是否已排好序,如果乱序,不输出内容,仅返回1
|
-b
| 会忽略每一行前面的所有空白部分,从第一个可见字符开始比较
|
举例如下:
例一:
sort的-r选项sort默认的排序方式是升序,如果想改成降序,如下:
[root@MiWiFi-R1CL-srv ~]# sort -r file
ffffffff
dddddddd
cccccccc
cccccccc
bbbbbbbb
aaaaaaaa
例二:在输出行中去除重复行
[root@MiWiFi-R1CL-srv ~]# cat file
bbbbbbbb
bbbbbbbb
cccccccc
dddddddd
ffffffff
cccccccc
ffffffff
aaaaaaaa
[root@MiWiFi-R1CL-srv ~]# sort -u file
aaaaaaaa
bbbbbbbb
cccccccc
dddddddd
ffffffff
例三:sort的-n选项,“要以数值来排序”
[root@MiWiFi-R1CL-srv ~]# cat file
1aaaaaaa
10aaaaaa
100aaaaa
10000aaa
[root@MiWiFi-R1CL-srv ~]# sort file
10000aaa
100aaaaa
10aaaaaa
1aaaaaaa
[root@MiWiFi-R1CL-srv ~]# sort -n file
1aaaaaaa
10aaaaaa
100aaaaa
10000aaa
例四:sort的-t选项和-k选项。
-t选项,设定间隔符。指定了间隔符之后,就可以用-k来指定列数进行排序。
[root@MiWiFi-R1CL-srv ~]# cat file
1aaaaaaa:23
10aaaaaa:1
100aaaaa:34
10000aaa:3
[root@MiWiFi-R1CL-srv ~]# sort -t':' -nk 2 file
10aaaaaa:1
10000aaa:3
1aaaaaaa:23
100aaaaa:34
指定分隔符,按照第二列整数进行排序
uniq
先看一个例子:
[root@MiWiFi-R1CL-srv ~]# cat file
aaaaaaa
eeeeeee
bbbbbbb
fffffff
ddddddd
bbbbbbb
bbbbbbb
ddddddd
ccccccc
[root@MiWiFi-R1CL-srv ~]# uniq file
aaaaaaa
eeeeeee
bbbbbbb
fffffff
ddddddd
bbbbbbb
ddddddd
ccccccc
[root@MiWiFi-R1CL-srv ~]# sort file | uniq
aaaaaaa
bbbbbbb
ccccccc
ddddddd
eeeeeee
fffffff
可以看出来,uniq的作用是去除相邻的重复行。
常用选项
选项
| 作用
|
-c
| 显示输出中,在每行行首加上本行在文件中出现的次数,它可取代-u和-d选项
|
-d
| 只显示重复行
|
-u
| 只显示文件中不重复的各行
|
举例如下,file文件内容如上:
[root@MiWiFi-R1CL-srv ~]# sort file | uniq -c
1 aaaaaaa
3 bbbbbbb
1 ccccccc
2 ddddddd
1 eeeeeee
1 fffffff
[root@MiWiFi-R1CL-srv ~]# sort file | uniq -d
bbbbbbb
ddddddd
[root@MiWiFi-R1CL-srv ~]# sort file | uniq -u
aaaaaaa
ccccccc
eeeeeee
fffffff
paste
概念
paste单词意思是粘贴。
该命令主要用来将多个文件的内容合并。paste将按行将不同文件行信息放在一行。
缺省情况下,paste连接时,用空格或tab键分隔新行中不同文本
我们看一个例子,两个文件的合并:
[root@MiWiFi-R1CL-srv ~]# cat file1
a
b
c
d
e
f
g
[root@MiWiFi-R1CL-srv ~]# cat file2
e
f
g
h
i
j
k
l
m
n
[root@MiWiFi-R1CL-srv ~]# paste file1 file2
a e
b f
c g
d h
e i
f j
g k
l
m
n
常见选项
选项
| 作用
|
-d
| 指定域分隔符
|
-s
| 将每个文件合并成行而不是按行粘贴
|
-
| 对每一个(-),从标准输入中读一次数据。默认使用空格或者tab作域分隔符,该选项可以定制输出格式
|
举例如下:
[root@MiWiFi-R1CL-srv ~]# paste -d# file1 file2
a#e
b#f
c#g
d#h
e#i
f#j
g#k
#l
#m
#n
[root@MiWiFi-R1CL-srv ~]# paste -d: file1 file2
a:e
b:f
c:g
d:h
e:i
f:j
g:k
:l
:m
:n
[root@MiWiFi-R1CL-srv ~]# paste -s -d: file1 file2
a:b:c:d:e:f:g
e:f:g:h:i:j:k:l:m:n
[root@MiWiFi-R1CL-srv ~]# ls /etc | paste - - - - -
abrt acpi adjtime aliases aliases.db
alsa alternatives anacrontab asound.conf at.deny
audisp audit avahi bash_completion.d bashrc
blkid bluetooth bonobo-activation centos-release chkconfig.d
ConsoleKit cron.d cron.daily cron.deny
cut
功能
cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。
如果不指定 File 参数, cut 命令将读取标准输入。必须指定 -b、-c 或 -f 标志之一。
选项
选项
| 作用
|
-b
| 以字节为单位进行分割
|
-c
| 以字符为单位进行分割
|
-d
| 自定义分隔符,默认为制表符
|
-f
| 与-d一起使用,指定显示哪个区域
|
举例如下:
-b:
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -b 1
h
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -b 1-3
hel
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -b 3
l
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -b 1,3
hl
-c:
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -c 1
h
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -c 1-3
hel
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -c 3
l
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -c 1,3
hl
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -c 1-
hello world
我们有必要知道,-c是以字符为单位,而-b只会以字节(8位二进制位)来计算,这里的字符,不是我们C当中的占有一个字节的字符。一个汉字也是一个字符,可以理解为是由多个字节组成的多字节字符。
-d,-f:
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -d' ' -f 1
hello
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -d' ' -f 1,2
hello world
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -d' ' -f 2
world
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -d' ' -f 1-
hello world
[root@MiWiFi-R1CL-srv ~]# echo "hello world" | cut -d' ' -f -2
hello world
xargs
这是一个很强大的工具。
概念:
- xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具。
- 它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。
- xargs也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。
- xargs的默认命令是echo,空格是默认定界符。这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。
使用
例一:
对文件进行格式化输出,将文件的多行输入转成单行输出。
[root@MiWiFi-R1CL-srv ~]# cat file
1 2 3 4
5 6 7 8
a b c d
e f g h
[root@MiWiFi-R1CL-srv ~]# cat file | xargs
1 2 3 4 5 6 7 8 a b c d e f g h
指定列数,并多行输出(-n):
[root@MiWiFi-R1CL-srv ~]# cat file | xargs -n3
1 2 3
4 5 6
7 8 a
b c d
e f g
h
自定义一个域分隔符,将特定列打散,并指定格式输出(-d)
[root@MiWiFi-R1CL-srv ~]# echo "a#b#c#d" | xargs -d#
a b c d
[root@MiWiFi-R1CL-srv ~]# echo "a#b#c#d" | xargs -d# -n1
a
b
c
d
[root@MiWiFi-R1CL-srv ~]# echo "a#b#c#d" | xargs -d# -n2
a b
c d
例二:
将格式化后的字符串作为命令行参数传递给其他命令,组装完成批量任务
[root@MiWiFi-R1CL-srv ~]# find /etc -name "*.cat" 2>/dev/null
/etc/sgml/xml-docbook-4.2-1.0-51.el6.cat
/etc/sgml/sgml-docbook-3.1-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.2-1.0-51.el6.cat
/etc/sgml/xml-docbook.cat
/etc/sgml/xml-docbook-4.5-1.0-51.el6.cat
/etc/sgml/sgml-docbook-3.0-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.3-1.0-51.el6.cat
/etc/sgml/xml-docbook-4.1.2-1.0-51.el6.cat
/etc/sgml/sgml-docbook.cat
/etc/sgml/sgml-docbook-4.1-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.0-1.0-51.el6.cat
/etc/sgml/xml-docbook-4.4-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.4-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.5-1.0-51.el6.cat
/etc/sgml/xml-docbook-4.3-1.0-51.el6.cat
[root@MiWiFi-R1CL-srv ~]# find /etc -name "*.cat" 2>/dev/null |xargs ls
/etc/sgml/sgml-docbook-3.0-1.0-51.el6.cat
/etc/sgml/sgml-docbook-3.1-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.0-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.1-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.2-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.3-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.4-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.5-1.0-51.el6.cat
/etc/sgml/sgml-docbook.cat
/etc/sgml/xml-docbook-4.1.2-1.0-51.el6.cat
/etc/sgml/xml-docbook-4.2-1.0-51.el6.cat
/etc/sgml/xml-docbook-4.3-1.0-51.el6.cat
/etc/sgml/xml-docbook-4.4-1.0-51.el6.cat
/etc/sgml/xml-docbook-4.5-1.0-51.el6.cat
/etc/sgml/xml-docbook.cat
例三:
使用-I指定一个替换字符串{},这个字符串在xargs扩展时会被替换掉,当-I与xargs结合使用, 每一个参数命令都会被执行一次:
[root@MiWiFi-R1CL-srv ~]# cat file
aaa
bbb
ccc
ddd
[root@MiWiFi-R1CL-srv ~]# cat test.sh
#!/bin/bash
echo $@
[root@MiWiFi-R1CL-srv ~]# cat file | xargs ./test.sh
aaa bbb ccc ddd
[root@MiWiFi-R1CL-srv ~]# cat file | xargs ./test.sh -a -b
-a -b aaa bbb ccc ddd
[root@MiWiFi-R1CL-srv ~]# cat file | xargs -I {} ./test.sh -a {} -b
-a aaa -b
-a bbb -b
-a ccc -b
-a ddd -b