目录
一、sort命令
1. sort的作用
2. 语法格式
3. 常用选项
4. 使用实例
二、uniq命令
1. uniq的作用
2. 语法格式
3. 常用选项
4. 使用实例
三、tr命令
1. tr的作用
2. 语法格式
3. 常用选项
4. 使用实例
四、cut命令
1. cut的作用
2. 语法格式
3. 常用选项
4. 使用实例
五、eval命令
1. eval的作用
2. 使用实例
总结
以行为单位对文件的内容进行排序,也可以根据不同的数据类型来排序。
sort [选项] 参数
cat file | sort 选项
常用选项 | 说明 |
---|---|
-f | 忽略大小写,会将小写字母都转换为大写字母来进行比较 |
-b | 忽略每行前面的空格 |
-n | 按照数字进行排序 |
-r | 反向排序 |
-u | 等同于uniq,表示相同数据仅显示一行 |
-t | 指定字段分隔符,默认使用[Tab]键分割 |
-k | 指定排序字段 |
-o <输出文件> | 将排序后的结果转存至指定文件 |
(1)sort命令
sort排序,首先比较每行第一个不为空的字符,按照空行>数字>字母(小写>大写)的优先级进行排序。若第一个字符相同,将比较第二个不为空的字符,以此类推。
[root@localhost ~]# cat test1.txt
one
two
three
four
five
six
seven
eight
Eight
EIGHT
1
11
12
2
3
4
[root@localhost ~]# sort test1.txt
1
11
12
2
3
4
eight
Eight
EIGHT
five
four
one
seven
six
three
two
(2)-f选项
使用-f选项,使得大写字母优先于小写字母排序。
[root@localhost ~]# sort -f test1.txt
12
1
11
2
3
4
EIGHT
Eight
eight
five
four
one
seven
six
three
two
(3)-n选项
由于sort命令是按照字符顺序进行比较,无法对数字进行有效排序。当我们需要对数字进行排序时,可使用-n选项。
[root@localhost ~]# sort -n test1.txt
eight
Eight
EIGHT
five
four
one
seven
six
three
two
1
2
3
4
11
12
(4)-r选项
使用-r选项,可以反向排序
[root@localhost ~]# sort -r test1.txt
two
three
six
seven
one
four
five
EIGHT
Eight
eight
4
3
2
12
11
1
(5)-u选项
使用-u选项,去重,将重复行显示为一行。
[root@localhost ~]# cat test2.txt
1
2
100
45
3
333
444
10
145
75
333
444
555
155
666
777
[root@localhost ~]# sort test2.txt
1
10
100
145
155
2
3
333
333
444
444
45
555
666
75
777
[root@localhost ~]# sort -u test2.txt
1
10
100
145
155
2
3
333
444
45
555
666
75
777
(6)-t -k选项
使用-t选项,可指定分隔符;-k选项指定排序列。
可使用“sort -t ':' -k3 -n /etc/passwd”命令对/etc/passwd文件的第三列按照数字大小进行排序。
[root@localhost ~]# sort -t ':' -k3 -n /etc/passwd
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
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
named:x:25:25:Named:/var/named:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
gdm:x:42:42::/var/lib/gdm:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
radvd:x:75:75:radvd user:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
qemu:x:107:107:qemu user:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
dhcpd:x:177:177:DHCP server:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
gnome-initial-setup:x:991:986::/run/gnome-initial-setup/:/sbin/nologin
sssd:x:992:987:User for sssd:/:/sbin/nologin
geoclue:x:993:988:User for geoclue:/var/lib/geoclue:/sbin/nologin
chrony:x:994:990::/var/lib/chrony:/sbin/nologin
setroubleshoot:x:995:993::/var/lib/setroubleshoot:/sbin/nologin
saslauth:x:996:76:Saslauthd user:/run/saslauthd:/sbin/nologin
colord:x:997:994:User for colord:/var/lib/colord:/sbin/nologin
libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
123456:x:1000:1000:123456:/home/123456:/bin/bash
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
(7)-o选项
-o选项,将排序结果输出到指定文件中
可使用“du -a /var | sort -nr -o var.txt”命令,将var目录中的文件大小进行按照所占大小顺序排序。
需注意的是,-o选项为直接覆盖操作,若需要保留文件内容,建议使用重定向追加。
[root@localhost ~]# du -a /var | sort -nr -o var.txt
[root@localhost ~]# vim var.txt
1028540 /var
587796 /var/cache
584424 /var/cache/yum/x86_64/7
584424 /var/cache/yum/x86_64
584424 /var/cache/yum
274456 /var/spool
274256 /var/spool/abrt
270716 /var/spool/abrt/ccpp-2021-07-01-13:19:58-22790
270412 /var/spool/abrt/ccpp-2021-07-01-13:19:58-22790/coredump
228080 /var/cache/yum/x86_64/7/updates
151324 /var/cache/yum/x86_64/7/base
151028 /var/cache/yum/x86_64/7/epel
142756 /var/cache/yum/x86_64/7/epel/gen
121116 /var/lib
117488 /var/cache/yum/x86_64/7/updates/packages
103524 /var/lib/rpm
101564 /var/cache/yum/x86_64/7/updates/gen
98576 /var/cache/yum/x86_64/7/base/gen
93768 /var/lib/rpm/Packages
82348 /var/cache/yum/x86_64/7/updates/packages/linux-firmware-20200421-80.git78c0348.el7_9.noarch.rpm
74052 /var/cache/yum/x86_64/7/epel/gen/filelists_db.sqlite
49724 /var/cache/yum/x86_64/7/local
48412 /var/cache/yum/x86_64/7/updates/gen/primary_db.sqlite
48056 /var/cache/yum/x86_64/7/base/gen/filelists_db.sqlite
45768 /var/cache/yum/x86_64/7/updates/gen/filelists_db.sqlite
42024 /var/cache/yum/x86_64/7/local/gen
36412 /var/cache/yum/x86_64/7/base/packages
30876 /var/cache/yum/x86_64/7/base/gen/primary_db.sqlite
30284 /var/cache/yum/x86_64/7/epel/gen/primary_db.sqlite
26976 /var/log
18952 /var/cache/yum/x86_64/7/epel/gen/updateinfo.xml
18672 /var/cache/yum/x86_64/7/epel/gen/other_db.sqlite
18500 /var/cache/yum/x86_64/7/local/gen/filelists_db.sqlite
18188 /var/cache/yum/x86_64/7/base/gen/other_db.sqlite
18168 /var/named
18120 /var/named/data
18064 /var/named/data/named.run-20210705
14588 /var/cache/yum/x86_64/7/local/gen/primary_db.sqlite
13872 /var/lib/yum
11848 /var/lib/yum/yumdb
9356 /var/log/messages-20210705
9024 /var/cache/yum/x86_64/7/updates/a053e36a58c0cc4916e18d6b0f3541aa2aaa96507aafc6b0425bb324c7dbfdf1-primary.sqlite.bz2
8232 /var/cache/yum/x86_64/7/updates/packages/kernel-tools-libs-3.10.0-1160.31.1.el7.x86_64.rpm
7464 /var/cache/yum/x86_64/7/local/gen/other_db.sqlite
7384 /var/cache/yum/x86_64/7/updates/gen/other_db.sqlite
用于报告或者忽略文件中连续的重复行,常与sort命令结合使用
uniq [选项] 参数
cat file | uniq 选项
常用选项 | 说明 |
---|---|
-c | 进行计数,并删除文件中重复出现的行 |
-d | 仅显示连续的重复行 |
-u | 仅显示出现一次的行 |
(1)uniq命令
对连续的重复行进行去重。
[root@localhost ~]# cat test3.txt
11
22
33
33
33
44
44
55
55
55
22
33
44
44
[root@localhost ~]# uniq test3.txt
11
22
33
44
55
22
33
44
若需要对全部行进行去重,可使用“sort -nu”命令或sort后进行uniq操作。
[root@localhost ~]# sort -nu test3.txt
11
22
33
44
55
[root@localhost ~]# sort -n test3.txt | uniq
11
22
33
44
55
(2)-c选项
使用-c选项,可统计出重复次数并进行去重
[root@localhost ~]# sort -n test3.txt | uniq -c
1 11
2 22
4 33
4 44
3 55
在日常运维中,我们需要对/var/log/secure目录进行计划性监控,以防止黑客的暴力破解。
可以将”grep "Failed password" /var/log/secure | awk '{print $11}' | uniq -c | awk '{print $1}'“该命令写入脚本中,如果该数字大于3次,就将该ip写入/etc/hosts.deny中,并将该脚本写入计划任务crontab中周期性监控。
[root@localhost ~]# grep "Failed password" /var/log/secure
Jul 25 20:54:10 localhost sshd[3512]: Failed password for root from 192.168.122.1 port 63504 ssh2
Jul 25 20:54:15 localhost sshd[3512]: Failed password for root from 192.168.122.1 port 63504 ssh2
Jul 25 20:54:16 localhost sshd[3512]: Failed password for root from 192.168.122.1 port 63504 ssh2
Jul 25 20:54:19 localhost sshd[3512]: Failed password for root from 192.168.122.1 port 63504 ssh2
Jul 25 20:54:22 localhost sshd[3512]: Failed password for root from 192.168.122.1 port 63504 ssh2
[root@localhost ~]# grep "Failed password" /var/log/secure | awk '{print $11}'
192.168.122.1
192.168.122.1
192.168.122.1
192.168.122.1
192.168.122.1
[root@localhost ~]# grep "Failed password" /var/log/secure | awk '{print $11}' | uniq -c
5 192.168.122.1
[root@localhost ~]# grep "Failed password" /var/log/secure | awk '{print $11}' | uniq -c | awk '{print $1}'
5
(3)-d选项
使用-d选项,仅显示连续的重复行
[root@localhost ~]# uniq -d test3.txt
33
44
55
44
若需要显示全部的重复行,可使用“sort -n”命令后进行"uniq -d"操作。
[root@localhost ~]# sort -n test3.txt | uniq -d
22
33
44
55
(4)-u选项
使用-u选项,仅显示不连续的不重复行
[root@localhost ~]# uniq -u test3.txt
11
22
22
33
若需要显示全部的不重复行,可使用“sort -n”命令后进行“uniq -u”操作
[root@localhost ~]# sort -n test3.txt | uniq -u
11
常用来对来自标准输入的字符进行替换、压缩和删除
tr [选项] [参数]
参数为所要操作的字符集,使用方式如下:
字符集1:指定要转换或删除的原字符集。当执行转换操作时,必须使用参数“字符集2”指定转换的目标字符集。但执行删除操作时,不需要参数“字符集2”。
字符集2:指定要转换成的目标字符集。
常用选项 | 说明 |
---|---|
-c | 保留字符集1的字符,其他的字符(包括换行符\n)用字符集2替换 |
-d | 删除所有属于字符集1的字符 |
-s | 将重复出现的字符串压缩为一个字符串;用字符集2替换字符集1 |
-t | 字符集2替换字符集1,不加选项同结果 |
(1)tr命令
tr命令可将字符集1中的字符替换为字符集2中的字符,并且是一一对应的关系,因此前后字符数需相同。
[root@localhost ~]# echo abc | tr "a-z" "A-Z"
ABC
[root@localhost ~]# echo abc | tr "b" "B"
aBc
[root@localhost ~]# echo abc | tr "cb" "BC"
aCB
将$PATH中的分隔符“:”转换为换行输出,使得可以通过列表的方式查看$PATH
[root@localhost ~]# echo $PATH | tr ":" "\n"
(2)-c选项
使用-c选项,可保留字符集1中的字符,其他非字符集1的字符(包括换行符\n)将被替换为字符集2中的字符。
[root@localhost ~]# echo -e "abc\ncabcdab" | tr -c "ab\n" "0"
ab0
0ab00ab
[root@localhost ~]# echo -e "abc\ncabcdab" | tr -c "ab" "0"
ab000ab00ab0[root@localhost ~]#
(3)-d选项
使用-d选项,可删除所有属于字符集1中的字符。
[root@localhost ~]# echo "hello world" | tr -d "ol"
he wrd
(4)-s选项
使用-s选项,可将重复的字符串压缩为一个字符串,也可以使用字符集2,将字符集1的字符替换为字符集2的字符后并进行压缩。
[root@localhost ~]# echo "helllllllllo wooooooorld" | tr -s "ol"
helo world
[root@localhost ~]# echo "helllllllllo wooooooorld" | tr -s "ol" "0"
he0 w0r0d
[root@localhost ~]# echo "helllllllllo wooooooorld" | tr -s "ol" " "
he w r d
也可通过“tr -s “\n””命令压缩空行
[root@localhost ~]# echo -e "aa\n\n\n\n\nbb"
aa
bb
[root@localhost ~]# echo -e "aa\n\n\n\n\nbb" |tr -s "\n"
aa
bb
将空格替换为“:”并进行输出,有以下几种方法
[root@localhost ~]# a=`echo -e "aa\n\n\n\n\nbb" |tr -s "\n" ":"`
[root@localhost ~]# echo $a
aa:bb:
[root@localhost ~]# echo ${a:0:5}
aa:bb
[root@localhost ~]# echo ${a%:}
aa:bb
(5)删除Windows文件造成的“^M”字符
Linux中遇到换行符“\n”会进行回车+换行的操作,回车符反而只会作为控制字符“^M”显示,不发生回车的操作。而Windows中要回车符+换行符“\r\n”才会正确的执行回车+换行操作,缺少一个控制符或者顺序不对都不能正确的另起一行。
一般情况下,我们无法察觉是否存在“^M”符号,可通过“cat -v”命令进行查看。
解决“^M”问题,也可以通过dos2unix软件进行修改
[root@localhost ~]# cat abc.txt
aa
bb
cc[root@localhost ~]#
[root@localhost ~]# cat -v abc.txt
aa^M
^M
bb^M
cc[root@localhost ~]#
方法一:
直接使用tr命令将“\r” 替换为“ ”,转化后的每行末尾都会有一个空格。
[root@localhost ~]# cat abc.txt | tr "\r" " " > ABC.txt
[root@localhost ~]# cat -v ABC.txt
aa
bb
cc[root@localhost ~]#
方法二:
使用“tr -s”命令将“\r”替换为" ",同上。
也可将“ ”换成“\n”,由于连续多个"\n"会被压缩为一个“\n”,因此若存在空行时将只换行一次,导致转换后不存在空行。
[root@localhost ~]# cat abc.txt | tr -s "\r" " " > ABC.txt
[root@localhost ~]# cat -v ABC.txt
aa
bb
cc[root@localhost ~]#
[root@localhost ~]# cat abc.txt | tr -s "\r" "\n" > ABC.txt
[root@localhost ~]# cat -v ABC.txt
aa
bb
cc[root@localhost ~]#
方法三:
使用“tr -d”命令删除“\r”,这也是最纯净的转换方式
[root@localhost ~]# cat abc.txt | tr -d "\r" > ABC.txt
[root@localhost ~]# cat -v 123.txt
aa
bb
cc[root@localhost ~]#
注:使用“cat”命令时,需替换掉“\r”;当使用的是“cat -v”命令时,应替换“^M”。
(6)将arr=(20 40 30 10 60 50)的数组按大小顺序排列
[root@localhost ~]# arr=(20 40 30 10 60 50)
[root@localhost ~]# echo ${arr[@]}
20 40 30 10 60 50
[root@localhost ~]# echo ${arr[@]} | tr " " "\n"
#将数组中的“ ”替换为“\n”换行符
20
40
30
10
60
50
[root@localhost ~]# echo ${arr[@]} | tr " " "\n" | sort -n
#对数字换行后的数字进行排序
10
20
30
40
50
60
[root@localhost ~]# num=`echo ${arr[@]} | tr " " "\n" | sort -n`
#设置变量num为数组中的数字
[root@localhost ~]# i=0
#设置变量i为数组中的下标,下标起始为0
[root@localhost ~]# for a in $num
> do
> arr[$i]=$a
> echo "下标$i为$a"
> let i++
> done
下标0为10
下标1为20
下标2为30
下标3为40
下标4为50
下标5为60
[root@localhost ~]# echo ${arr[@]}
10 20 30 40 50 60
显示行中的指定部分,删除文件中指定字段
cut 选项 参数
cat file | cut 选项
常用选项 | 说明 |
---|---|
-b | 以字节为单位进行分割 |
-c | 以字符为单位进行分割 |
-f | 通过指定哪一个字段进行提取。cut命令使用“Tab”作为默认的字段分隔符 |
-d | “Tab”是默认的字段分隔符,使用此选项可以更改为其他的分隔符 |
--complement | 此选项用于排除所指定的字段 |
--output-delimiter | 更改输出内容的分隔符 |
(1)-d -f选项
截取指定字段
截取系统中的用户名
[root@localhost ~]# cut -d ':' -f 1 /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
systemd-network
dbus
polkitd
abrt
libstoragemgmt
rpc
colord
saslauth
setroubleshoot
rtkit
pulse
qemu
ntp
radvd
chrony
tss
usbmuxd
geoclue
sssd
gdm
rpcuser
nfsnobody
gnome-initial-setup
avahi
postfix
sshd
tcpdump
123456
以指定条件截取/etc/passwd文件中的第1-4、6、7字段
[root@localhost ~]# grep 'bin/bash' /etc/passwd
root:x:0:0:root:/root:/bin/bash
123456:x:1000:1000:123456:/home/123456:/bin/bash
[root@localhost ~]# grep 'bin/bash' /etc/passwd | cut -d ':' -f 1-4,6,7
root:x:0:0:/root:/bin/bash
123456:x:1000:1000:/home/123456:/bin/bash
截取登录失败信息
[root@localhost ~]# grep "Failed password" /var/log/secure
Jul 25 20:54:10 localhost sshd[3512]: Failed password for root from 192.168.122.1 port 63504 ssh2
Jul 25 20:54:15 localhost sshd[3512]: Failed password for root from 192.168.122.1 port 63504 ssh2
Jul 25 20:54:16 localhost sshd[3512]: Failed password for root from 192.168.122.1 port 63504 ssh2
Jul 25 20:54:19 localhost sshd[3512]: Failed password for root from 192.168.122.1 port 63504 ssh2
Jul 25 20:54:22 localhost sshd[3512]: Failed password for root from 192.168.122.1 port 63504 ssh2
[root@localhost ~]# grep "Failed password" /var/log/secure | cut -d ' ' -f 11
192.168.122.1
192.168.122.1
192.168.122.1
192.168.122.1
192.168.122.1
[root@localhost ~]# grep "Failed password" /var/log/secure | cut -d ' ' -f 11 | uniq -c
5 192.168.122.1
[root@localhost ~]# grep "Failed password" /var/log/secure | cut -d ' ' -f 11 | uniq -c | tr -s " "
5 192.168.122.1
[root@localhost ~]# grep "Failed password" /var/log/secure | cut -d ' ' -f 11 | uniq -c | tr -s " " | cut -d ' ' -f 2
5
(2)--complement -f选项
排除指定字段
[root@localhost ~]# grep 'bin/bash' /etc/passwd | cut -d ':' --complement -f 2
root:0:0:root:/root:/bin/bash
123456:1000:1000:123456:/home/123456:/bin/bash
(3)--output-delimiter选项
更改指定字段的分隔符
[root@localhost ~]# cut -d ':' -f 1,7 --output-delimiter=' ' /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin
systemd-network /sbin/nologin
dbus /sbin/nologin
polkitd /sbin/nologin
abrt /sbin/nologin
libstoragemgmt /sbin/nologin
rpc /sbin/nologin
colord /sbin/nologin
saslauth /sbin/nologin
setroubleshoot /sbin/nologin
rtkit /sbin/nologin
pulse /sbin/nologin
qemu /sbin/nologin
ntp /sbin/nologin
radvd /sbin/nologin
chrony /sbin/nologin
tss /sbin/nologin
usbmuxd /sbin/nologin
geoclue /sbin/nologin
sssd /sbin/nologin
gdm /sbin/nologin
rpcuser /sbin/nologin
nfsnobody /sbin/nologin
gnome-initial-setup /sbin/nologin
avahi /sbin/nologin
postfix /sbin/nologin
sshd /sbin/nologin
tcpdump /sbin/nologin
123456 /bin/bash
(4)-b选项
以字节为单位截取指定字符
[root@localhost ~]# i=1234567890
[root@localhost ~]# echo $i | cut -b 3-6
3456
[root@localhost ~]# echo ${i:2:4}
3456
[root@localhost ~]# expr substr $i 3 4
3456
命令字前加上eval时,shell会在执行命令之前扫描它两次。eval命令将首先会去扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量。该命令对变量进行两次扫描。
[root@localhost ~]# echo "hello world" > file
[root@localhost ~]# myfile="cat file"
[root@localhost ~]# echo $myfile
cat file
[root@localhost ~]# eval $myfile
hello world
[root@localhost ~]# vim test.sh
```
#!/bin/bash
eval echo \$$#
```
[root@localhost ~]# ./test.sh 1 3 5 7 9
9
[root@localhost ~]# a=100
[root@localhost ~]# b=a
[root@localhost ~]# eval $b=50
[root@localhost ~]# echo $a
50
干货满满,值得阅读