管道命令

1. 管道命令

管道命令【 | 】仅能处理经由前面一个命令传来的正确信息(也就是标准输出的信息),对于标准错误并没有直接处理能力

管道命令的处理示意图:

管道命令需要注意的地方:

  • 管道命令仅会处理标注输出,对于标准错误予以忽略
  • 管道命令必须能够接受来自前一个命令的数据成为标准输入继续处理才行

如果强制让标准错误被管道命令使用,应该使用数据流重定向,让2>&1加入命令中,让2>变成1>

1.1 选取命令:cut、grep

选取就是将一段数据经过分析后
第一种情况:取出我们想要的(cut)
第二种情况:经由分析所需信息,取得所需信息所在行(grep)

1.1.0 cut(以行为单位,将一段信息的某一片段信息切出来)

用法:

[dmtsai@study ~] cut -d '分割字符' -f fields
[dmtsai@study ~] cut -c 字符区间
-b : 以字节为单位进行分割 ,仅显示行中指定直接范围的内容
-c : 以字符为单位进行分割 , 仅显示行中指定范围的字符
-d : 自定义分隔符,默认为制表符”TAB”
-f : 显示指定字段的内容 , 与-d一起使用
-n : 取消分割多字节字符
--complement : 补足被选择的字节、字符或字段
--out-delimiter : 指定输出内容是的字段分割符

范例1:
将PATH变量取出,找出第三个和第五个路径

[dmtsai@study ~] echo ${PATH}

[dmtsai@study ~] echo ${PATH} | cut -d ':' -f 3,5

范例2:
将export输出的信息,取第12个字符以后的所有字符

[dmtsai@study ~] export

[dmtsai@study ~] export | cut -c 12- #将export输出的信息,取第12个字符以后的所有字符

1.1.1 grep(分析所需信息,取得所需信息的所在行)

用法:

[dmtsai@study ~] grep [-parameter] [-color=auto] '查找字符' filename
-i : 搜索时,忽略大小写
-c : 只输出匹配行的数量
-l : 只列出符合匹配的文件名,不列出具体的匹配行
-n : 列出所有的匹配行,显示行号
-h : 查询多文件时不显示文件名
-s : 不显示不存在、没有匹配文本的错误信息
-v : 显示不包含匹配文本的所有行
-w : 匹配整词
-x : 匹配整行
-r : 递归搜索
-q : 禁止输出任何结果,已退出状态表示搜索是否成功
-b : 打印匹配行距文件头部的偏移量,以字节为单位
-o : 与-b结合使用,打印匹配的词据文件头部的偏移量,以字节为单位

范例1:
在last的输出信息中,将出现 reboot 这个字符的所在行显示出来

[dmtsai@study ~] last

[dmtsai@study ~] last | grep 'reboot'

范例2:
在last的输出信息中,将没有出现 reboot 这个字符的所在行显示出来

[dmtsai@study ~] last | grep -v 'reboot' # -v : 显示不包含匹配文本的所有行

范例3:
在last的输出信息中,只要有reboot就取出,且仅取出第一栏

[dmtsai@study ~] last | grep 'reboot' | cut -d ' ' -f 1 #单引号内空一格即分隔符为空格

范例4:
取出【/etc/man_db.conf】内含MANPATH的那几行

[dmtsai@study ~] grep --color=auto 'MANPATH' /etc/man_db.conf

1.2 排序命令:sort、wc、uniq

1.2.0 sort(根据不同的数据形式来排序)

如果需要进行排序时,建议使用【LANG=C】来统一语系,这样数据排序较好

用法:

[dmtsai@study ~] sort [-parameter] [file or stdin]
-b : 忽略每行前面开始出的空格字符
-c : 检查文件是否已经按照顺序排序
-d : 排序时,处理英文字母、数字及空格字符外,忽略其他的字符
-f : 排序时,将小写字母视为大写字母
-i : 排序时,除了040至176之间的ASCII字符外,忽略其他的字符
-m : 将几个排序号的文件进行合并
-M : 将前面3个字母依照月份的缩写进行排序
-n : 依照数值的大小排序
-o <输出文件> :	将排序后的结果存入制定的文件
-r : 以相反的顺序来排序
-t <分隔字符> :	指定排序时所用的栏位分隔字符
-k : 指定需要排序的栏位

范例1:
将账号进行排序(个人账号都记录在【/etc/passwd】)

[dmtsai@study ~] cat /etc/passwd | sort

范例2:
【/etc/passwd】内容是以 :来分隔的,现在想以第三栏来排序(按文字来排序)

[dmtsai@study ~] cat /etc/passwd | sort -t ':' -k 3 #按文字来排序
[dmtsai@study ~] cat /etc/passwd | sort -t ':' -k # 3 -n    #这里为注释:按数字来排序

范例3:
利用last显示最近账户登录信息,将输出的数据仅显示账号,并加以排序

[dmtsai@study ~] last | cut -d ' ' -f1 | sort

1.2.1 uniq(用来去除文本文件中连续的重复行,中间不能夹杂其他文本行)

用法:

[dmtsai@study ~] uniq [-parameter]
-c : 打印每行在文本中重复出现的次数
-d : 只显示有重复的纪录,每个重复纪录只出现一次
-u : 只显示没有重复的纪录

范例1:
使用last将账号列出,仅取出账号栏,进行排序后仅取出一位

[dmtsai@study ~] last

[dmtsai@study ~] last | cut -d ' ' -f 1 | sort | uniq


统计每个账户登录次数

[dmtsai@study ~] last | cut -d ' ' -f 1 | sort | uniq -c

1.2.2 wc(统计指定文件中的字节数、字数、行数,并将统计结果显示输出)

用法:

[dmtsai@study ~] wc [-parameter]
-w : 统计字数,或--words:只显示字数。一个字被定义为由空白、跳格或换行字符分隔的字符串
-c : 统计字节数,或--bytes或--chars:只显示Bytes数
-l : 统计行数,或--lines:只显示列数
-m : 统计字符数
-L : 打印最长行的长度
--help : 显示帮助信息
--version :	显示版本信息

范例1:
查看【/etc/man_db.conf】里有多少相关字、行、字符数

[dmtsai@study ~] cat /etc/man_db.conf | wc
    131    723    5171 #行、字数、字符数

范例2:
由于last会输出空白行、wtmp、unknown、reboot等无关账号内容,利用grep取出非空白行,以及去除上述关键字所在行,再计算行数

[dmtsai@study ~] last

[dmtsai@study ~] last | grep [a-zA-Z] | grep -v 'wtmp' | grep -v 'reboot' | \
> grep -v 'unknown' | wc -l     # -v : 显示不包含匹配文本的所有行
18

1.3 双向重定向:tee

tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件

tee会同时将数据流分送到文件与屏幕

tee的工作流程示意图:

用法:

[dmtsai@study ~] tee [-parameter] file
-a : 附加到既有文件的后面,而非覆盖它
-i : 忽略中断信号
— help : 查看帮助信息
— version :	显示版本信息

范例1:
将last输出数据保存一份到 last.list 文件中

[dmtsai@study ~] last | tee last.list | cut -d ' ' -f 1
# last的输出数据被保存到last.list文件中
# 将last.list中的数据,以空格为分隔符取出第一段,并在终端直接显示


last 的输出数据被保存到 last.list 文件

1.4 字符转换命令:tr、col、join、paste、expand

1.4.0 tr(transform,转换)

tr:一种可将字符进行替换、压缩、删除,可以将一组字符转换成另一组字符

用法:

[dmtsai@study ~] tr  [-parameter] [string1] [string2]
-c : 选定字符串1中字符集的补集,即反选字符串1的补集
-d : 删除字符串1中出现的所有字符
-s : 删除所有重复出现的字符序列,只保留一个

范例1:
在last 输出信息中,所有的小写变成大写字符

[dmtsai@study ~] last | tr '[a-z]' '[A-Z]' #也可以不加单引号


范例2:
在【/etc/passwd】输出的信息中,删除冒号(:)

[dmtsai@study ~] cat /etc/passwd 

[dmtsai@study ~] cat /etc/passwd | tr -d ':' #-d : 删除字符串1中出现的所有字符


范例3:
将【/etc/passwd】转成dos换行,并保存到【/root/passwd】中,再将^M符号删除
(在Vim中,DOS换行符与UNIX换行符不同,可用dos2unix与unix2dos来转换)

[dmtsai@study ~] cp /etc/passwd ~/passwd && unix2dos ~/passwd
[dmtsai@study ~] file /etc/passwd ~/passwd
/etc/passwd:         ASCII text
/home/dmtsai/passwd: ASCII text, with CRLF line terminators #DOS换行
[dmtsai@study ~] cat ~/passwd | tr -d '\r' > ~/passwd.Linux # \r指的就是DOS换行符

1.4.1 col(colation,过滤)

col:该命令是一个标准输入文本过滤器,它从标注输入设备读取文本内容,并把内容显示到标注输出设备

用法:

[dmtsai@study ~] col [-parameter]
-b : 过滤掉所有的控制字符,包括RLF和HRLF
-f : 滤除RLF字符,但允许将HRLF字符呈现出来
-x : 以多个空格字符来表示跳格字符
-l<缓冲区列数> :	预设的内存缓冲区有128列,您可以自行指定缓冲区的大小

范例:
利用【cat -A】显示出所有特殊按键,最后以 col 将 [Tab] 转成空白

[dmtsai@study ~] cat -A /etc/man_db.conf # ^I代表 [Tab]
# cat 用于查看文件内容的命令 【-A】等价于【-vET】组合
#【-v】使用 ^ 和 M- 引用,除了 LFD 和 TAB 之外
#【-E】每行结束处显示$符号
#【-T】将TAB字符显示为 ^I符号
[dmtsai@study ~] cat /etc/man_db.conf | col -x | cat -A | more #[Tab]按键被替换成为空格键

1.4.2 join(join,加入)

join:将两个具有相同域的纪录给挑选出来,再将这些纪录所有的域放到一行(要整合的内容中如有相同的内容,则整合后不会重复显示)

注意:join在对两个文件进行连接时,两个文件必须都是按照连接域排好序的,按其他域排序是无效的

用法:

[dmtsai@study ~] join [-parameter] file1 file2
-a1或-a2 : 除了显示共同域的纪录之外,-a1显示第一个文件没有共同域的纪录,-a2显示第二个文件中没有共同域的纪录
-i : 忽略大小写
-o : 设置结果显示的格式
-t : 改变域的分隔符
-v1或-v2 : 不显示共同域的纪录之外,-v1显示第一个文件没有共同域的纪录,-v2显示第二个文件中没有共同域的纪录
-1或-2 : -1用来设置文件1连接的域,-2用来设置文件2连接的域

范例1:
用root身份,将【/etc/passwd】和【/etc/shadow】相关数据整合成一栏

[root@study ~] head -n 3 /etc/passwd /etc/shadow #head 以行为单位,取文件的内容,后面不接参数时默认打印前10行,这里显示3行

[dmtsai@study ~] join -t ':' /etc/passwd /etc/shadow | head -n 3 #【-t】: 改变域的分隔符

将【/etc/passwd】和【/etc/shadow】具有相关性的内容放置在同一行,并以冒号(:)分隔
如前者root后的数据和后者root后的数据放置在同一行

范例2:

[root@study ~] head -n 3 /etc/passwd /etc/group

[dmtsai@study ~] join -t ':' -1 4 /etc/passwd -2 3 /etc/group | head -n 3
# [-t]: 改变域的分隔符
# -1或-2 : -1用来设置文件1连接的域,-2用来设置文件2连接的域
# head 以行为单位,取文件的内容,后面不接参数时默认打印前10行,这里显示3行
0:root:x:0:root:/root:/bin/bash:root:x:
1:bin:x:1:bin:/bin:/sbin/nologin:bin:x:
2:daemon:x:2:daemon:/sbin:/sbin/nologin:daemon:x:

join之前应该先对上述两个文件进行排序,不排序会出现下图情况

1.4.3 paste(paste,粘贴)

paste:把每个文件以列对列的方式,一列列地加以合并 ,他就是相当于把两个不同的文件内容粘贴在一起,形成新的文件

注意:paste默认粘贴方式以列的方式粘贴,但是并不是不能以行的方式粘贴,加上-s选项就可以行方式粘贴。

用法:

[dmtsai@study ~] paste [-parameter] file1 file2
-d : 默认域的分隔符是空格或tab键,设置新的域分隔符
-s : 将每个文件粘贴成一行
-- : 从标准输入中读取数据

范例1:
用 root 身份,将【/etc/passwd】与【/etc/shadow】同一行贴在一起

[root@study ~] paste /etc/passwd /etc/shadow


范例2:
用cat将【/etc/group】读出来,然后与【/etc/passwd】与【/etc/shadow】贴在一起,且仅取出前三行

[root@study ~] cat /etc/group | paste /etc/passwd /etc/shadow - | head -n 3
# cat /etc/group  :cat用于查看文件内容的命令
# paste /etc/passwd /etc/shadow -  :将这两个文件相关内容贴在同一行 【-】 代表stdin或stdout
# head -n 3 :head 以行为单位,取文件的内容,后面不接参数时默认打印前10行,这里显示3行

1.4.4 expand(转换为空白字符)

用法:

[dmtsai@study ~] expand [-parameter]
-t : 指定制表符所代表的空白字符的个数,而不使用默认的8。
-i : 不转换非空白符后的制表符
--help : 显示帮助信息
--version :	显示版本信息

范例:
将【/etc/man_db.conf】内行首为MANPATH的字样就取出来,仅取前三行

[dmtsai@study ~] grep '^MANPATH' /etc/man_db.conf | head -n 3
MANPATH_MAP /bin   /usr/share/man
MANPATH_MAP /usr/bin  /usr/share/man
MANPATH_MAP /sbin   /usr/share/man
# grep 分析所需信息,取得所需信息的所在行
# head -n 3 :head 以行为单位,取文件的内容,后面不接参数时默认打印前10行,这里显示3行

承上,将所有的符号都列出来

[dmtsai@study ~] grep '^MANPATH' /etc/man_db.conf | head -n 3 | cat -A
MANPATH_MAP^I/bin^I^I^I/usr/share/man$
MANPATH_MAP^I/usr/bin^I^I/usr/share/man$
MANPATH_MAP^I/sbin^I^I^I/usr/share/man$
# cat 用于查看文件内容的命令 【-A】等价于【-vET】组合
#【-v】使用 ^ 和 M- 引用,除了 LFD 和 TAB 之外
#【-E】每行结束处显示$符号
#【-T】将TAB字符显示为 ^I符号

承上,将[Tab]按键设置成6个字符

[dmtsai@study ~] grep '^MANPATH' /etc/man_db.conf | head -n 3 | expand -t 6 - | cat -A
MANPATH_MAP /bin   /usr/share/man$
MANPATH_MAP /usr/bin  /usr/share/man$
MANPATH_MAP /sbin   /usr/share/man$
# expand 的功能是转换为空白字符
#expand -t : 指定制表符所代表的空白字符的个数,而不使用默认的8,这里改为了6
# - 代表stdin或stdout

1.5 划分命令:split(将大文件分割成较小的文件)

split:将大文件分割成较小的文件,在默认情况下将按照每1000行切割成一个小文件

用法:

[dmtsai@study ~] split [-parameter] 切割文件 filename
-b : 指定每多少字节切成一个小文件
--help : 查看帮助信息
--version : 显示版本信息
-C : 与参数”-b”相似,但是在切割时将尽量维持每行的完整性

范例1:
假设【/etc/services】600多K,将其分成300K一个文件

[dmtsai@study ~] cd /tmp; split -b 300k /etc/services services
[dmtsai@study tmp] ll -k services*
-rw-rw-r--  1  dmtsai  dmtsai  307200  Jul  9  22:52  servicesaa
-rw-rw-r--  1  dmtsai  dmtsai  307200  Jul  9  22:52  servicesab
-rw-rw-r--  1  dmtsai  dmtsai   55893  Jul  9  22:52  servicesac

将上述三个文件合成一个文件,文件名为servicesback

[dmtsai@study ~] cat services* >> serviceback # cat读取三个文件内容后 >> 累加到一个文件中

范例2:
使用【ls -al /】输出的信息中,每十行记录成一个文件

[dmtsai@study ~] ls -al / | split -l 10 - lsroot
[dmtsai@study tmp] wc -l lsroot*
10 lsrootaa
10 lsrootab
 4 lsrootac
24 total 
# - 代表stdin或stdout

1.6 参数代换:xargs(给其他命令传递参数的一个过滤器,也可组合多个命令)

x是乘号,args是arguments,xargs就是产生某个命令的参数的意思

xargs:给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具
它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者 stdin 并将其转换成特定命令的命令参数

用法:

[dmtsai@study ~] xargs [-parameter]
-n : 多行输出
-d : 自定义一个定界符
-I : 指定一个替换字符串{}
-t : 打印出 xargs 执行的命令
-p : 执行每一个命令时弹出确认

范例1:
将【/etc/passwd】内的第一栏取出,仅取三行,使用id命令将每个账号内容显示出来

[dmtsai@study ~] id root # id命令可查询使用者的 UID/GID 等信息
#id命令可以显示真实有效的用户ID(UID)和组ID(GID)
#UID 是对一个用户的单一身份标识
#组ID(GID)则对应多个UID


错误示范1:

[dmtsai@study ~] id $(cut -d ':' -f 1 /etc/passwd | head -n 3)

虽然使用 $(cmd)预先取得参数,但 id 这个命令【仅能接受一个参数】
上述命令执行会出现错误,不会显示用户的ID


错误示范2:

[dmtsai@study ~] cut -d ':' -f 1 /etc/passwd | head -n 3 | id


因为 id 并不是管道命令,因此上述此命令执行后,前面的东西通通不见,只会执行 id


错误示范3:

[dmtsai@study ~] cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs id

因为 xargs 一口气将全部的数据通通丢给 id 处理,但 id 仅能最多接受1个


正确示范:

[dmtsai@study ~] cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id
# -n : 多行输出
# 通过[-n]来处理,一次给予一个参数,结果显示正常


范例2:
同上,但每次执行 id 时,都要询问使用者是否操作

[dmtsai@study ~] cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -p -n 1 id
# -n : 多行输出
# -p : 执行每一个命令时弹出确认

范例3:
将所有的【/etc/passwd】内的账号都以 id 查看,但查到 sync 就结束命令串

[dmtsai@study ~] cut -d ':' -f 1 /etc/passwd | xargs -e 'sync' -n 1 id
# cut -d '分割字符' -f fields
# -e (end of file),后接一个字符,当xargs分析到此字符时,就会停止工作
# -n 后接次数,每次command命令执行时,要使用几个参数的意思
# id命令可以显示真实有效的用户ID(UID)和组ID(GID)。UID 是对一个用户的单一身份标识。组ID(GID)则对应多个UID

范例4:
使用【xargs】的原因:很多命令并不支持管道命令,因此可通过xargs来提供该命令使用标准输入(stdin)

找出【/usr/sbin】下具有特殊权限的文件名,并使用【ls -l】列出详细属性

[dmtsai@study ~] find /usr/sbin -perm /7000 | xargs ls -l

1.7 关于【-】的用途

在管道命令中,常常会使用到前一个命令的 stdout (标准输出)作为这次的 stdin(标准输入),某些命令需要用到文件名(如tar)来进行处理时,该stdin与stdout可利用减号【-】来替代

范例:

[dmtsai@study ~] mkdir /tmp/homeback
[dmtsai@study ~] tar -cvf - /home | tar -xvf - -C /tmp/homeback
# tar命令可以为linux的文件和目录创建档案
#[-c]建立新的备份文件
#[-v]显示指令执行过程 
# -f<备份文件> 指定备份文件
#[-x]从归档文件中提取文件
# -C <目录>	切换工作目录,先进入指定目录再执行压缩/解压缩操作,可用于仅压缩特定目录里的内容或解压缩到特定目录

将 /home 里的文件打包,但打包的数据不记录到文件,而是传送到stdout(标准输出),经过管道后(pipe),将【-cvf - /home】传送到后面的【tar -xvf -】,后面这个【-】则是使用前一个命令的stdout,因此,我们不需要使用文件名

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Uncertainty!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值