摘要:管道命令概述、常见管道命令的使用(cut/grep、sort/wc/uniq、tee、tr/col/join/paste/expand、xargs、减号-)
一、概述
命令执行完会在屏幕上打印相应的数据,但这些数据可能要经过几道手续之后才能成为我们所想要的格式。而中间经过的这几道手续就与我们所要用的管道命令有关了。
管道命令与“连续执行命令”是不一样的!!
管道命令使用的界定符号是“|”!!
【管道命令的要求】
- 管道命令仅能处理经由前面一个命令传来的正确信息,也就是standard output的信息,对于standard error并没有直接处理的能力。
- 在每个管道后面接的第一个数据必定是“命令”,而且这个命令必须要能够接收standard input的数据。
二、选取命令
选取命令:就是将一段数据经过分析后,取出我们所想要的;或者是经由分析的关键字,取得我们所想要的那一行。
一般说来,选取信息通常是针对“行”来分析的,并非整篇信息分析的。
1. cut
【概述】
将一段信息的某一段“切”出来,处理的信息是以“行”为单位的。
【用途】
主要的用途在于将同一行里面的数据进行分解(在一行信息中取出某部分我们想要的)。
最常使用在分析一些数据或文字数据的时候,因为有时候我们会以某些字符当作切割的参数,然后来将数据加以切割,以取得我们所需要的数据。
【使用】
分隔字符:cut -d '分隔字符' -f fields //-f会依据-d的分隔字符将一段信息切割成为数段,用-f取出第几段的意思
排列整齐的信息:cut -c 字符范围 //-c会以字符的单位取出固定字符区间
【示例】
题目1:将PATH变量取出,找出第五个路径。
命令:echo $PATH | cut -d ':' -f 5
题目2:将PATH变量取出,找出第三、五个路径。
命令:echo $PATH | cut -d ':' -f 3,5
题目3:在export输出的信息中,取每一行的第12以后的字符
命令:export | cut -c 12-
题目4:在export输出的信息中,取每一行的第12-20字符
命令:export | cut -c 12-20
题目5:用last在显示的登录者信息中仅留下用户名
命令:last | cut -d ' ' -f 1
2. grep
【概述】
分析一行信息,若当中有我们所需要的信息,就将该行拿出来。
【用途】
可以解析一行文字,取得关键字,若该行存在关键字,就会整行列出来。
【用法】
grep [-cinv] [--color=auto] '查找字符串' filename //-c计算找到'查找字符串'的次数;-i忽略大小写;-n输出行号;-v反向选择
【示例】
题目1:将last当中有出现root的那一行取出来
命令:last | grep 'root'
题目2:与题目1相反,只要没有root的就取出
命令:last | grep -v 'root'
题目3:在last的输出信息中,只要有root就取出,并且仅取该行的第一列
命令:last | grep 'root' | cut -d ' ' -f 1
题目4:取出/etc/man.config内含MANPATH的那几行
命令:grep 'MANPATH' /etc/man.config
三、排序命令
1. sort
【概述】
可以帮我们进行排序,还可以依据不同的数据类型来排序。例如,数字与文字的排序就不一样。
此外,排序的字符与语系的编码有关,因此,如果你需要排序时,建议使用LANG=C来让语系统一。
【用途】
常用于比较一些信息,如要知道最大的用户ID是多少。
【用法】
sort [-bfntk] [file/stdin]
//-b忽略最前面的空格符部分、-f忽略大小写、-n使用纯数字进行排序(默认是以文字类型来排序的)、-t后接分隔符(默认是Tab)、-k为第k个区间来进行排序
【示例】
题目1:个人账户都记录在/etc/passwd下,请将账号进行排序
命令:cat /etc/passwd | sort
题目2:/etc/passwd内容是以:来分隔的,我想以第三列来排序,该如何办?
命令:cat /etc/passwd | sort -t ':' -k 3
题目3:利用last将输出的数据仅取账号,并加以排序
命令:last | cut -d ' ' -f1 | sort
2. uniq
【概述】
排序完成后,将重复的数据仅列出一个显示。(即需要配合排序过的文件来处理)
【用途】
将重复的行删除掉只显示一个,如查看登录的用户数(而不要重复显示同一用户的多次登录情况)
【用法】
uniq [-c] //-c进行计数
【示例】
题目1:使用last将账号列出,仅取出账号列,进行排序后仅取出一位
命令:last | cut -d ' ' -f 1| sort | uniq
题目2:承题目1,我还想知道每个人的登录总次数
命令:last | cut -d ' ' -f 1| sort | uniq -c
3. wc
【概述】
相当有用的计算文件内容的一个工具组。
【用途】
帮我们计算输出的信息的整体数据,如计算一个文件里有多少字/行/字符。由此,我们可以知道账号文件中的账号数目(cat /etc/passwd | wc -l),因为/etc/passwd里面一行代表一个用户啊,所以知道行数就晓得有多少的账号在里头了。
【用法】
wc [-lwm] //-l仅列出行、-w仅列出多少字(英文单字)、-m列出有多少字符
【示例】
题目1:计算/etc/man.config里面到底有多少相关字、行、字符数
命令:cat /etc/man.config | wc
题目2:我知道使用last可以输出登陆者,但是last最后两行并非账号内容,那么我该如何以一行命令串取得这个月份登录系统的总人次?
命令:last | grep [a-zA-Z] | grep -v 'wtmp' | wc -l
四、双向重定向:tee
【概述】
我们之前使用>将stdout导入文件或设备,除非我们去读取该文件或设备,否则就无法继续利用这个stdout。
tee会同时将数据流送与文件与屏幕,而输出到屏幕的就是stdout,可以让下个命令继续处理。
【用途】
tee可以让stdout转存一份到文件内并将同样的数据继续送到屏幕去处理。
这样,除了可以让我们同时分析一份数据并记录下来之外,还可以作为处理一份数据的中间暂存盘记录之用。
【用法】
tee [-a] file //-a以累加的方式,将数据加入file中
【示例】
示例1:last | tee last.list | cut -d " " -f1
解释:让我们将last的输出存一份到last.list文件中
示例2:ls -l /home | tee ~/homefile | more
解释:将ls的数据存一份到~/homefile,同时屏幕也有输出信息
示例3:ls -l / | tee -a ~/homefile | more
解释:tee后接的文件会被覆盖,所以我们加上-a参数来将信息累加
五、字符转换命令
我们知道vim编辑器当中DOS断行字符与UNIX断行字符的不同,并且可以使用dos2UNIX与UNIX2dos来完成转换。
很显然,我们应该有其他常用的字符替代——大小写转换、[Tab]按键与空格键的转换,以及将两篇信息整合成一篇。
我们要讨论的就是字符转换命令在管道当中的使用方法。
1. tr
【用途】
删除一段信息当中的文字,或者是进行文字信息的替换。
【用法】
tr [-ds] SET1 ... //-d为删除信息当中的SET1这个字符串;-s为替换掉重复的字符串
【示例】
题目1:将last输出的信息中所有的小写字符变成大写字符
命令:last | tr '[a-z]' '[A-Z]' 或 last | tr [a-z] [A-Z]
题目2:将/etc/passwd输出的信息中的冒号(:)删除
命令:cat /etc/passwd | tr -d ':'
题目3:将/etc/passwd转存成dos断行到/root/passwd中,再将^M符号删除
命令:cp /etc/passwd /root/passwd && UNIX2dos /root/passwd; cat /root/passwd | tr -d '\r' > /root/passwd.linux
2. col
【用途】
将[tab]按键替换成为空格键;将man page转存为纯文本文件以方便查阅
【用法】
col [-xb] //-x为将tab键转换成对等的空格键、-b则是在文字内有/时,仅保留/最后接的那个字符
【示例】
题目1:利用cat -A显示出所有的特殊按键,最后以col将[tab]转成空白
命令:cat -A /etc/man.config; cat /etc/man.config | col -x | cat -A | more
题目2:将col的man page转存成为/root/col.man的纯文本文件
命令:man col > /root/col.man; man col | col -b > /root/col.man
3. join
【用途】
处理两个文件之间的数据 ,而且主要是将两个文件当中有相同数据的那一行加在一起。
【注意】
join在处理两个相关的数据文件时,是很有帮助的。根据两个文件之间的相关性,我们可以将有关系的数据放置在一起。这在处理数据是相当有帮助的。
需要注意的是,在使用join之前,需处理的文件应该要事先经过排序处理,以免略过某些项目。
【用法】
join [-t12] file1 file2
-t后接分隔符(默认为空格),并且对比“第一字段”的数据,如果两个文件相同,则将两条数据连成一行,且第一个字段放在第一个;
-1代表file1要用哪个字段来分析,-2代表file2要用哪个字段来分析的意思。
【示例】
题目1:用root的身份,将/etc/passwd与/etc/shadow相关数据整合成一行
命令:join -t ':' /etc/passwd /etc/shadow
评讲:将两个文件的第一字段相同者整合成一行,第二个文件的相同字段并不会显示(因为两个文件中的相同字段会在第一列显示)
题目2:我们知道/etc/passwd的第四个字段是GID,那个GID记录在/etc/group当中的第三个字段,该如何将两个文件整合
命令:join -t ':' -1 4 /etc/passwd -2 3 /etc/group
评讲:相同的字段部分被移动到最前面
4. paste
【概述】
相对于join必须要对比两个文件的数据相关性,paste就直接将两行贴在一起,且中间以[tab]键隔开而已。
【用法】
paste [-d] file1 file2 //-d后面可以接分隔字符(默认为Tab)、如果文件部分写成-,表示来自standard input的数据的意思
【示例】
题目1:将/etc/passwd和/etc/shadow同一行粘贴在一起
命令:paste /etc/passwd /etc/shadow
题目2:先将/etc/group读出,然后与题目1粘贴在一起,且仅取出前三行
命令:cat /etc/group | paste /etc/passwd /etc/shadow - | head -n 3
评讲:重点是-的使用,这经常代表stdin 。
5. expand
【用途】
将[Tab]按键转成空格键
【用法】
expand [-t] file //-t后接数字,一般是8,但你也可以自行定义一个[Tab]按键代表多少个字符
【示例】
题目1:将/etc/man.config内行首为MANPATH的字样取出,仅取前三行
命令:grep '^MANPATH' /etc/man.config | head -n 3
题目2:承上,如果我想要将所有的符号都列出来的话?
命令:grep '^MANPATH' /etc/man.config | head -n 3 | cat -A
题目3:承上,我将[Tab]按键设置成6个字符的话?
命令:grep '^MANPATH' /etc/man.config | head -n 3 | expand -t 6 - | cat -A
六、切割命令:split
【概述】
如果文件过大,我们可以将它切割成多个小文件啊!
【用途】
将一个大文件依据文件大小或行数来切割成为小文件
【用法】
split [-bl] file 切割文件的前导文字 //-b后接欲切割成的文件大小(可带单位,如b,k,m等)、-l为以行数来进行切割
【示例】
题目1:我的/etc/term文件有700多KB,若想要分为300KB一个文件时怎么办?
命令:cd /tmp; split -b 300k /etc/term term
评讲:term是自己设置的前导文字,那么得到的3个小文件的名字就分别为termaa, termab, termac
题目2:如何将上面的三个小文件合成一个文件,文件名为termback
命令:cat term* >> termback
题目3:将使用ls -al /输出的信息中,每10行记录成一个文件
命令:ls -al / | split -l 10 - lsroot
评讲:重点在于-,一般来说,-会被当成stdin或stdout
七、参数代换:xargs
【概述】
xargs就是在产生某个命令的参数的意思。
xargs可以读入stdin的数据,并且以空格符或断行字符进行分辨,将stdin的数据分隔成为arguments。
因为是以空格符作为分隔,所以,如果有一些文件名或者是其他意义的名词内含有空格符的时候,xargs可能就会误判了。
【用法】
xargs [-epn] command //未接任何参数时,默认是以echo来进行输出
-e:这个是EOF的意思,后面接一个字符串,当xargs分析到这个字符串时,就会停止继续工作
-p:在执行每个命令的参数时,都会询问用户的意思
-n:后面接次数,每次command命令执行时,要使用几个参数的意思。
【示例】
题目1:将/etc/passwd内的第一列取出,仅取三行,使用finger这个命令将每个账号的内容显示出来。
命令:cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs finger
说明:我们利用cut取出账号名称,用head取出三个账号,最后由xargs将三个账号的名称变成finger后面需要的参数
题目2:同上,但是每次执行finger时,都要询问用户是否操作。
命令:cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -p finger
题目3:将所有的/etc/passwd内的账号都以finger查阅,但一次仅查阅五个账号
命令:cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -p -n 5 finger
说明:一般来说,某些命令后面可以接的参数是有限制的,不能无限制地累加,此时我们可以利用-n来帮助我们将参数分成数个部分,每个部分分别再以命令来执行。
题目4:同上,但是分析到lp就结束这串命令
命令:cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -p -e 'lp' finger
题目5:找出/sbin下面具有特殊权限的文件名,并使用ls -l 列出详细属性
错误命令:find /sbin -perm +7000 | ls -l //因为ls -l并非管道命令
正确命令:find /sbin -perm +7000 | xargs ls -l //xargs产生ls命令的参数(即find找到的文件名)
八、关于减号(-)的用途
在管道命令中,经常会使用到前一个命令的stdout作为这次的stdin,某些命令需要用到文件名(例如tar)来进行处理时,该stdin与stdout可以利用“-”来替代。
举例:tar -cvf - /home | tar -xvf -
在上面这个例子中,我们将/home里面的文件打包,但打包的数据不是记录到文件,而是传送到stdout;经过管道后,将tar -cvf - /home传送给后面的tar -xvf -。后面的这个-这是取用前一个命令的stdout,因此我们就不需要使用文件了。