Shell 管道指令grep、tr、sort、xargs

管道命令pipe

1.管道命令仅处理标准输出,对于标准错误输出会省略。
2.管道命令必须能够接受来自前一个命令的数据作为标准输入继续处理才行

选取命令 cut、grep

一段数据经过分析后,取出我们要的。或是经由分析关键词,取出我们想要的

选取信息通常是针对一行一行来分析的

cut 取出需要的信息

将一行信息当中,取出我们想要的信息,处理信息以行为单位

语法
用于有特定分割字符
cut -d ‘分割字符’ -f 第几个字段(从1开始计数)

用于排列整齐的信息,以字符的单位取出固定字符区间
cut -c 字符区间

选项和参数
-d 后面接分隔字符,与-f一起使用
-f fields 根据-d划分的段数,取出第几段
-c 以字符的单位取出固定字符区间

案例

取出PATH的第三个字段

[ranan@c105 ~]$ echo $PATH
/home/mpi/bin:/home/ranan/.local/bin:/home/ranan/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
[ranan@c105 ~]$ echo $PATH | cut -d ':' -f 3,4
/home/ranan/bin
[ranan@c105 ~]$ echo $PATH | cut -d ':' -f 3-5
/home/ranan/bin:/usr/local/bin:/usr/bin

取出每行的前5个字符

[ranan@c105 ~]$ echo $PATH | cut -c 1-5
/home

grep 取出需要行、过滤不需要的行

分析一行信息,若当中有我们需要的信息,就把一行拿出来
可以先grep取出一行再利用cut取出需要的信息。

语法

grep [-A] [-B] [-acinv] [–color=auto] ‘查找字符’ filename

选项与参数
-a 将二进制文本以文本文件的方式查找数据
-c count计算找到’查找字符’的此时
-i ignore忽略大小写
-n 输出行号
-v 反向输出没有字符的那些行
–color=auto 可以将找到的部分加上颜色显示,centOS7之后,默认

-A 后面可以添加数字,after 除了输出该行外,后面的n行也输出
-B 后面可以添加数字,before 除了输出该行外,前面的n行也输出

[ranan@c105 ~]$ last -n 5
ranan    pts/1        192.168.10.1     Fri Dec  3 15:53   still logged in
ranan    pts/0        192.168.10.1     Fri Dec  3 10:11    gone - no logout
reboot   system boot  4.18.0-240.22.1. Fri Dec  3 10:11   still running
ranan    pts/0        192.168.10.1     Thu Dec  2 20:49 - 09:52  (13:03)
reboot   system boot  4.18.0-240.22.1. Thu Dec  2 20:49 - 09:52  (13:03)

wtmp begins Sun May 23 20:25:21 2021

[ranan@c105 ~]$ last -n 5 | grep -n -A1  '192'
1:ranan    pts/1        192.168.10.1     Fri Dec  3 15:53   still logged in
2:ranan    pts/0        192.168.10.1     Fri Dec  3 10:11    gone - no logout
3-reboot   system boot  4.18.0-240.22.1. Fri Dec  3 10:11   still running
4:ranan    pts/0        192.168.10.1     Thu Dec  2 20:49 - 09:52  (13:03)
5-reboot   system boot  4.18.0-240.22.1. Thu Dec  2 20:49 - 09:52  (13:03)

排序命令 sort、wc、uniq

使用场景: 计算一次数据里面的相同形式的数据总数

sort 排序

sort可以根据不同的数据形式来排序,sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。

语法

sort [-fbMnrtuk][-o<输出文件>][-t<分割字符>] [+<起始栏位>-<结束栏位>] [file or stdin]

常见参数

-f 忽略大小写
-b 忽略每行开始的空格字符
-M 以月份的名字来排序
-m 将几个排序好的文件进行整合
-n 使用数值的大小排序
-o<输出文件>将排序后的结果存入指定的文件
-r 降序,默认升序
-c 检查文件是否已经按照顺序排序
-u uniq,去重配合-c,严格校验,不配合-c,则只输出一次排序结果,一般用uniq代替。
-t<分隔字符> 指定排序时所用的栏位分隔字符,默认[Tab]来分隔
-k 选第几列或第几列的第几个字符排序

案例

个人账号都记录在/etc/passwd下,将账号进行排序

[ranan@c105 ~]$ cat /etc/passwd | sort

image

/etc/passwd内容以:分割,我们以第三栏

[ranan@c105 ~]$ cat /etc/passwd | sort -t ':' -k 3
# 按数字排列
[ranan@c105 ~]$ cat /etc/passwd | sort -t ':' -k 3 -n

默认是以ASCII排列

image

按数字排序

image

假设三位数,按十位数从小到大,个位数从大到小排序。
[ranan@c105 ~]$ cat number.txt
991
454
522
258
322
[ranan@c105 ~]$ sort -n -k 1.2 -k 1.3nr number.txt # 为什么不行!错误写法
322
522
454
258
991
[ranan@c105 ~]$ sort -n -k 1.2,1.2 -k 1.3nr number.txt #第一列的第2个字符,从小到大,第一列的第三个字符,从大到小 这里r也就是-r
322
522
258
454
991

注意这里排序的第一种写法是错误的,省略了End部分,这就意味着你将对从第二个字母起到本域最后一个字符为止的字符串进行排序。如果不设定End部分,那么就认为End被设定为行尾,但是从小到大是只需要十位,不需要个位,所以需要限定。

把排序的结果输出到源文件

输出到其他文件可以使用 >
输出到同名文件使用 -o 文件名

[ranan@c105 ~]$ cat number.txt | sort -k 1.2 > number.txt
[ranan@c107 ~]$ sort -k 1.2 number.txt > newnumber.txt #不同名的可以
[ranan@c107 ~]$ cat newnumber.txt 
91
52
34
45
29
[ranan@c105 ~]$ cat number.txt #number.txt为空了说明同名的是不可以的
# 使用-o
[ranan@c105 ~]$ cat number.txt 
34
45
52
29
91
[ranan@c105 ~]$ cat number.txt | sort -k 1.2 -o number.txt
[ranan@c105 ~]$ cat number.txt
91
52
34
45
29
-u与-k的结合

-u只识别用-k设定的域,发现相同,就将后续相同的行都删除。

如果有两层排序,-u是会权衡所有-k选项,将都相同的才会删除,只要其中有一级不同都不会轻易删除的。

注意:如果遇见跨域,跨域的设定是个假象,不会跨域比较

[ranan@c105 ~]$ cat facebook.txt 
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
[ranan@c105 ~]$ sort -n -k 2 facebook.txt 
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
[ranan@c105 ~]$ sort -n -k 2 -u facebook.txt 
guge 50 3000
baidu 100 5000
google 110 5000

uniq 去重

如果排序完成了,将重复的数据仅列出一个显示可以使用uniq

语法
uniq [-ic]

-i 忽略大小写
-c 进行重复出现的计数
-u 只显示不重复的行
-d 只显示重复的行

uniq最好结合排序使用,因为unqi只会将挨着的重复行删除

[ranan@c105 ~]$ last | cut -d ' ' -f 1
ranan
reboot
ranan
ranan
[ranan@c105 ~]$ last | cut -d ' ' -f 1 | uniq
ranan
reboot
ranan
[ranan@c105 ~]$ last | cut -d ' ' -f 1 | sort |uniq

ranan
reboot

wc 统计

wc可以统计一个文件里面有多少字,多少行,多少字符,可以帮我们计算输出信息的整体数据

语法
wc [-lwm]

-l 列出行
-w 列出多少字(英文字母)
-m 多少字符

注意
如果只使用wc 默认是按lwm的顺序输出
后面不能直接接文件!,可以使用标准输入

wc -l < nowcoder.txt

字符转化指令tr

tr 命令用于转换字符、删除字符和压缩重复的字符。它从标准输入读取数据并将结果输出到标准输出。

语法tr [OPTION]... SET1 [SET2]

SET1:指定要转换或删除的原字符集。当执行转换操作时,必须使用参数“字符集2”指定转换的目标字符集。但执行删除操作时,不需要参数“字符集2”;
SET2:指定要转换成的目标字符集

选项
-d 可以删除指定的字符,不需要设置set2
-c 取反操作,取指定字符外的其他字符,与-d 组合选项,可以删除指定的字符外的其他字符
-s(squeeze-repeats) 将SET1中指定的连续重复的字符用单个字符替代,可以使用**-s ‘\n’**删除空行。
-t set1多出来的默认会用set2中的替换,-t只替换对应的字符,多出的不替换。

字符集代码
字符集代码:

[:alnum:] 字母和数字,可以用来替代’a-zA-Z0-9’
[:alpha:] 字母,可以用来替代’a-zA-Z’
[:cntrl:] 控制(非打印)字符
[:digit:] 数字,可以用来替代’0-9’
[:graph:] 图形字符
[:lower:] 小写字母,可以用来替代’a-z’
[:print:] 可打印字符
[:punct:] 标点符号
[:space:] 空白字符
[:upper:] 大写字母,可以用来替代’A-Z’
[:xdigit:] 十六进制字符

替换

如果参数 SET1 和 SET2 同时制定,并没有指定 -d 选项,那么 tr 命令将把 SET1 中指定的每个字符替换为 SET2 中相同位置的字符。
如果SET1的字符长度大于SET2,那么将SET1中多出来的字符用SET2中的最后一个字符替换。

将小写字母转换为大写字母,这里是a替换成A、b替换成B,不是把abcdefghijklmnopqrstuvwxyz替换成ABCDEFGHIJKLMNOPQRSTUVWXYZ

cat filename | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
cat filename | tr a-z A-Z
cat filename | tr [:lower:] [:upper:]  //使用正则

压缩字符

这里不是替换sa 而是a字符,s字符

echo "thisssssasasa is aaaaa" | tr -s "sa"
thisasasa is a

参数替换 xargs

产生某个命令的参数

作用

  • 将管道或stdin数据转换成命令行参数,调用只能接受命令行参数的命令。
  • xargs的输入会包含换行和空白,通过xargs,换行和空白会被空格取代
  • 组合多命令的,有些命令无法通过管道,它可以捕获一个命令的输出然后传递给另一个指令
  • 单行或多行文本输入转换成其他格式,比如单行变多行,多行变单行

语法

xargs [-0epn] 命令

xargs命令接受来自stdin的输入,将数据解析成单个元素,然后调用指定命令并将这些元素作为该命令的参数。xargs默认使用空白字符分割输入并执行echo。

-0 如果输入的stdin含有特殊字符,如` \ 空格等字符时,-0可以将它还原成一般字符
-e EOF(end of file),后面接一个字符,当xargs分析到这个字符时,就会停止工作。
-nx 选项可以限制每次调用命令时用到的参数x个
-d 输入数据指定自定义的分割符,默认是空格
-p 询问用户是否执行该命令
-a file 从文件中读入作为 stdin
-t 表示先打印命令,然后再执行。

案例

多行变成单行

默认换行和空白被空格取代

cat test.txt
a b c
d f g
h i j
cat test.txt | xargs
a b c d f g h i j
单行变多行
cat test.txt
a:b:c:d:f:g:h:i:j
cat test.txt | xargs -d ':' -n2 # 每次取两个参数
a b 
c d 
f g
h i
j
将/etc/passwd内第一列取出,仅取三行,使用这个id命令将每个账号内容显示出来

id 用户名

[ranan@MPI0 ~]$ id ranan
uid=1000(ranan) gid=1000(ranan)=1000(ranan),10(wheel)

根据需求,我们先把将/etc/passwd内第一列取出,仅取三行

[ranan@MPI0 ~]$ cat /etc/passwd | cut -d ':' -f1 | head -n3
root
bin
daemon

所以现在我们需要把上面的值作为id的参数,是不行的,因为id后面只能跟一个参数,这个时候就可以使用参数替换了xargs

# 错误写法
[ranan@MPI0 ~]$ id $(cat /etc/passwd | cut -d ':' -f1 | head -n3)
id: 额外的操作数 “bin”
请尝试执行 "id --help" 来获取更多信息。

# 正确写法
[ranan@MPI0 ~]$ cat /etc/passwd | cut -d ':' -f1 | head -n3 | xargs -n1 id
uid=0(root) gid=0(root)=0(root)
uid=1(bin) gid=1(bin)=1(bin)
uid=2(daemon) gid=2(daemon)=2(daemon)
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值