sort

sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file
u
t
x
y
u
t
u
t
u
x
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort file
t
t
t
u
u
u
u
x
x
y

常用选项

sort默认为按照ASCII码升序排列,如果想改变排序方式直接加个-r就按照降序排序

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort file
t
t
t
u
u
u
u
x
x
y
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort -r file
y
x
x
u
u
u
u
t
t
t

如果想将排序后的内容去重可以加-u选项可以达到去除效果

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort -r file
y
x
x
u
u
u
u
t
t
t
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort -ru file
y
x
u
t

sort的-n选项,“要以数值来排序”

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file
1abcja
2kndjsk
1ldslldsa
2kdsak
3mdksak
1ksa
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort -n file
1abcja
1ksa
1ldslldsa
2kdsak
2kndjsk
3mdksak
#按照字符串首字母大小来排序

sort的-t选项和-k选项.-t选项,可以设定间隔符。指定了间隔符之后,就可以用-k来指定列数进行排序。

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file
abc.123
abc.124
abc.124
abc.126
abc.120
abc.122
abc.121
abc.12.
abc.12,
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort -t'.' -nk 3 file## 按照’.‘后边第3列字符排序
abc.12,
abc.12.
abc.120
abc.121
abc.122
abc.123
abc.124
abc.124
abc.126


其他选项

-f会将小写字母都转换为大写字母来进行比较,亦即忽略大小写
-c会检查文件是否已排好序,如果乱序,则输出第一个乱序的行的相关信息,最后返回1
-C会检查文件是否已排好序,如果乱序,不输出内容,仅返回1
-b会忽略每一行前面的所有空白部分,从第一个可见字符开始比较。

uniq

uniq用于检查文本文件中重复出现的行列,一般与sort命令结合使用

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file
1111
1111
2222
2222
3333
4444
1111
3333
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort file | uniq #先将file文件中数据排序然后去重
1111
2222
3333
4444
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# uniq file #直接去重只能去掉相邻重复数据
1111
2222
3333
4444
1111
3333

常用选项

  • -c: 显示输出中,在每行行首加上本行在文件中出现的次数。它可取代-u和-d选项。
  • -d: 只显示重复行
  • -u: 只显示文件中不重复的各行。
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file
1111
1111
2222
2222
3333
4444
1111
3333
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort file | uniq -c #排序file文件中数据并将出现次数显示在第一列
      3 1111
      2 2222
      2 3333
      1 4444
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort file | uniq -d #排列file文件数据并将文件中重复数据显示出来
1111
2222
3333
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort file | uniq -u # 显示file文件中不重复的数据
4444

sort, uniq 工具,求file1和file2的交集,并集,补集

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file1
1111
2222
3333
4444
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file2
1111
2222
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort file1 file2 | uniq -d   #先排序两个文件中数据写进管道中然后uniq -d显示重复行就可以了
1111
2222
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# sort file1 file2 | uniq -u #显示文件中没有出现的 也就是两个文件中没有重复出现的数据
3333
4444

paste

paste单词意思是粘贴。该命令主要用来将多个文件的内容合并。paste将按行将不同文件行信息放在一行。缺省情况下, paste连接时,用空格或tab键分隔新行中不同文本

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# clear
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file1
1111
2222
3333
4444
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file2
1111
2222
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# paste file1 file2 #将文件按行数据放在一起中间用空格隔开
1111	1111
2222	2222
3333	
4444

常用选项

  • -d: 指定域分隔符
  • -s: 将每个文件合并成行而不是按行粘贴。
  • -: 你没有看错, - 确实是该命令的一个选项。对每一个(-),从标准输入中读一次数据。默认使用空格或者tab作域分隔符,该选项可以定制输出格式
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file1
1
2
3
4
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file2
a
b
c
e

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# paste -d : file1 file2 #文件每行数据之间指定分隔符
1:a
2:b
3:c
4:e
:
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# paste -d : -s file1 file2 #因为只有两个文件所以只有两行 都是将每个文件中数据按行为一个单位中间用':'分离
1:2:3:4
a:b:c:e:
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~] ls /etc | paste - - - - - -
abrt acpi adjtime aliases aliases.db alsa
alternatives anacrontab ansible 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 cron.hourly cron.monthly crontab cron.weekly crypttab
csh.cshrc csh.login cups dbus-1 default depmod.d
dhcp DIR_COLORS DIR_COLORS.256color DIR_COLORS.lightbgcolor dnsmasq.conf dnsmasq.d
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]  ls /etc | paste -d# - - - - - -
abrt#acpi#adjtime#aliases#aliases.db#alsa
alternatives#anacrontab#ansible#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#cron.hourly#cron.monthly#crontab#cron.weekly#crypttab

cut

cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。 如果不指定 File 参数,cut 命令将读取标准输入。必须指定 -b、-c 或 -f 标志之一。

常用选项

  • -b :以字节为单位进行分割。
  • -c :以字符为单位进行分割。
  • -d :自定义分隔符,默认为制表符。
  • -f :与-d一起使用,指定显示哪个区域。
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# echo "hello" | cut -b 1 #剪切第一个字符
h
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# echo "hello" | cut -b 1-5 #剪切1-5个字符
hello
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# echo "hello" | cut -b 3 #剪切第3个字符
l
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# echo "hello" | cut -b 3,1 #剪切第1个和第3个字符
hl
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# echo "hello" | cut -b 3,1,5 #剪切第 1 3 5个字符
hlo
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# echo "hello" | cut -c 1
h
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# echo "hello" | cut -c 3,1,5
hlo
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# echo "hello" | cut -c 1-5
hello
####### 看起来这-c选项和-b选项没有多大差别看下边的操作
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]#  echo "你好" | cut -c 1[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]#  echo "你好" | cut -c 2[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]#  echo "你好" | cut -c 1-2
你好
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]#  echo "你好" | cut -b 1
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]#  echo "你好" | cut -b 2
􀳦
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]#  echo "你好" | cut -b 1-2
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]#  echo "你好" | cut -b 1-3[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# echo "你好" | cut -b 1-6
你好

#差距立马就显示出来了
用-c则会以字符为单位,输出正常;而-b只会以字节(8位二进制位)来计算,输出就是乱码。这里的字符,不是我们C当中的占有一个字节的字符!可以简单理解成,汉字是由多个字节组成的多字节字符

xargs

使用

对文件进行格式化输出,将文件的多行输入转成单行输出。
-n选项:指定列数,并多行输出
-d选项: 自定义一个域分隔符,将特定列打散,并指定格式输出
将格式化后的字符串作为命令行参数传递给其他命令,组装完成批量任务

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file
1 2 3 4
5 6 7 8
a b c d
e f g h
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file | xargs    ##将文件内容传话成行输出
1 2 3 4 5 6 7 8 a b c d e f g h
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file | xargs -n 3   ## 将文件数据中数据每行只有3列数字 然后输出
1 2 3 
4 5 6
7 8 a
b c d
e f g
h
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# echo "a#b#c#" | xargs -d#  ##自定义分节符  以自定义分界符将数据分割然后输出
a b c 
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# echo "a#b#c#" | xargs -d# -n 2  ##先将数据按照自定义分界符分割,然后按照一行指定行输出
a b
c

## 将格式化后的字符串作为命令行参数传递给其他命令,组装完成批量任务
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]#  find /etc -name "*.cat" 2>/dev/null
/etc/sgml/xml-docbook.cat
/etc/sgml/sgml-docbook-4.3-1.0-51.el6.cat
/etc/sgml/xml-docbook-4.4-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.1-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.5-1.0-51.el6.cat
/etc/sgml/sgml-docbook-3.0-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.0-1.0-51.el6.cat
/etc/sgml/xml-docbook-4.3-1.0-51.el6.cat
/etc/sgml/sgml-docbook.cat
/etc/sgml/xml-docbook-4.2-1.0-51.el6.cat
/etc/sgml/xml-docbook-4.1.2-1.0-51.el6.cat
/etc/sgml/xml-docbook-4.5-1.0-51.el6.cat
/etc/sgml/sgml-docbook-3.1-1.0-51.el6.cat
....
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]#  find /etc -name "*.cat" 2>/dev/null | xargs ls
/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.2-1.0-51.el6.cat
/etc/sgml/sgml-docbook-3.1-1.0-51.el6.cat /etc/sgml/sgml-docbook-4.4-1.0-51.el6.cat
/etc/sgml/xml-docbook-4.3-1.0-51.el6.cat
/etc/sgml/sgml-docbook-4.0-1.0-51.el6.cat /etc/sgml/sgml-docbook-4.5-1.0-51.el6.cat
......
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# find /etc -name "*.cat" 2>/dev/null | xargs ls -al
total 80
dr-xr-x---.  6 root root  4096 Apr 22 18:44 .
dr-xr-xr-x. 18 root root  4096 Apr 20 13:21 ..
-rw-r--r--   1 root root 12288 Apr 20 17:49 .1.sh.swp
-rw-------   1 root root  6923 Apr 21 19:20 .bash_history
-rw-r--r--.  1 root root    18 Dec 29  2013 .bash_logout
-rw-r--r--.  1 root root   176 Dec 29  2013 .bash_profile
-rw-r--r--.  1 root root   176 Dec 29  2013 .bashrc
drwx------   3 root root  4096 Sep 14  2020 .cache
-rw-r--r--.  1 root root   100 Dec 29  2013 .cshrc
-rw-r--r--   1 root root    32 Apr 22 18:44 file
drwxr-xr-x   2 root root  4096 Nov 30 07:17 .pip
drwxr-----   3 root root  4096 Apr 20 22:01 .pki
-rw-r--r--   1 root root   206 Apr 20 10:17 .pydistutils.cfg
drwx------   2 root root  4096 Sep 14  2020 .ssh
-rw-r--r--.  1 root root   129 Dec 29  2013 .tcshrc
-rw-------   1 root root  5777 Apr 22 18:44 .viminfo

xargs的一个选项-I,使用-I指定一个替换字符串{},这个字符串在xargs扩展时会被替换掉,当-I与xargs结合使用,每一个参数命令都会被执行一次:

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file
1 2 3 4
5 6 7 8
a b c d
e f g h
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file | xargs echo $@
1 2 3 4 5 6 7 8 a b c d e f g h
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file | xargs echo $@ -a -b
-a -b 1 2 3 4 5 6 7 8 a b c d e f g h
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file | xargs -I {} echo $@ -1 {} -2
-1 1 2 3 4 -2
-1 5 6 7 8 -2
-1 a b c d -2
-1 e f g h -2

创建根目录下的文件和目录的同名文件.log

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# ls /
bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# ls / | xargs -I {} touch {}.log
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# ls
bin.log   dev.log  file      lib64.log  lost+found.log  mnt.log  proc.log  run.log   srv.log  tmp.log  var.log
boot.log  etc.log  home.log  lib.log    media.log       opt.log  root.log  sbin.log  sys.log  usr.log
## 删除.log文件
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# ls / | xargs -I {} rm {}.log
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# ll
total 4
-rw-r--r-- 1 root root 32 Apr 22 18:44 file

find, xargs, rm混合

## 首先创建一些文件
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# i=0; while [ $i -le 10 ]; do touch file$i; let i+=1; done
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# ls
file  file0  file1  file10  file2  file3  file4  file5  file6  file7  file8  file9

## 使用xargs命令将其覆盖
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# find . -name "file*" -print0 | xargs -0 rm
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# ll
total 0

其中,有关find命令print0 选项,和xargs命令的-0 选项 man 手册

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# touch file\ bak
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# ls
file bak
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# find . -name 'file*'
./file bak
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# find . -name 'file*' | xargs rm
rm: cannot remove `./file': No such file or directory
rm: cannot remove `bak': No such file or directory
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# find . -name 'file*' -print0
./file bak[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# find . -name 'file*' -print0 | xargs -0 rm
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# ls
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]#

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]#

grap

grep是一款强大的文本过滤工具,按照关键字或者正则表达式进行行过滤
grep命令:过滤出指定关键字的行;
格式:grep [参数] ‘字符’ filename

常用选项

grep -n 显示符号要求的行,并显示行号
grep -c 打印符合要求的行数
grep -v 打印不符合要求的行,取反的意思
grep -r 会把目录下的所有文件全部遍历;-r针对的是目录,如果不加-r只能针对文件
grep -i 忽略大小写
grep -A2 打印符合要求的行以及下面两行
grep -B2 打印符合要求的行以及上面两行
grep -C2 打印符合要求的行以及上下两行
grep -w 匹配一个完整的单词
grep -E 特殊符号脱意==egrep
centos7中自带 --color显示颜色 ;
grep 跟特殊符号的话,要用单引号
grep --include 包含
grep -l 只打印出含有匹配字符串的文件名,不输出具体匹配行的数据

## 过滤出包含cat的行
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# history > file  ##将指定历史重定向到文件file
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# cat file
    1  quit
    2  exit
    3  ll
  [root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# grep 'cat' file
   10  cat /etc/shells
   38  cat test.sh
   51  cat test.sh
   59  cat test.sh
   62  cat test.sh
   65  cat test.sh
   70  cat test.sh
   84  cat tesr.sh
# grep –n 过滤出包含cat的行,并显示行号;
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# grep -n 'cat' file  ##前边就是型添加的行号
10:   10  cat /etc/shells
38:   38  cat test.sh
51:   51  cat test.sh
59:   59  cat test.sh
62:   62  cat test.sh
65:   65  cat test.sh
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# grep -c 'cat' file ##统计要筛选的行数
110

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# grep -v 'cat' file ##显示出没有包含筛选对象的行数据
    1  quit
    2  exit
    3  ll
    4  clear
    5  ll
    6  history
    7  ! 1
    8  ll
    9  sh
   11  vim hello.sh
   12  ./hello.sh
   [root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# grep -i 'CAT' file ##不分大小写筛选
   10  cat /etc/shells
   38  cat test.sh
   51  cat test.sh
   59  cat test.sh
   62  cat test.sh
   65  cat test.sh
   70  cat test.sh

[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# grep -A2 'cat' file  ##显示要筛选的行数据之外还显示下边没有符合筛选要求的行数据
   10  cat /etc/shells
   11  vim hello.sh
   12  ./hello.sh
--
   38  cat test.sh
   39  ./test.sh
   40  pwd
[root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# grep -B2 'cat' file ##显示要筛选的行数据之外还显示上边没有符合筛选要求的行数据
    8  ll
    9  sh
   10  cat /etc/shells
--
   36  pwd
   37  ll
   38  cat test.sh

  [root@iZ8vbhcpwdmnwpx91dy1h8Z ~]# grep -C2 'cat' file ##打印符合要求的行以及这行上下各两行;就是包含要筛选的数据的上下都没有符合筛选要求的行数据个两行
    8  ll
    9  sh
   10  cat /etc/shells
   11  vim hello.sh
   12  ./hello.sh
--
   36  pwd
   37  ll
   38  cat test.sh
   39  ./test.sh
   40  pwd

其他就不详细介绍了

更多推荐

shell脚本常见开发工具