bash 命令执行的时候有输出的数据会出现!如果这群数据必需要经过几道手续之后才能得到我们所想要的格式,应该如何来设定? 这就牵涉到管线命令的问题了 (pipe) ,管线命令使用的是“ | ”这个界定符号! 另外,管线命令与“连续下达命令”是不一样的!底下我们先举一个例子来说明一下简单的管线命令。
例子: 假设我们想要知道 /etc/ 底下有多少档案,那么可以利用 ls /etc 来查阅,不过, 因为 /etc 底下的档案太多,导致一口气就将屏幕塞满了,不知道前面输出的内容是什么?此时,我们可以透过 less 指令的协助,利用:
[root@www ~]# ls -al /etc | less如此一来,使用 ls 指令输出后的内容,就能够被 less 读取,并且利用 less 的功能,我们就能够前后翻动相关的信息了!很方便是吧?其实这个 管线命令“ | “仅能处理经由前面一个指令传来的正确信息,也就是 standard output 的信息,对于 stdandard error 并没有直接处理的能力。
在每个管线后面接的第一个数据必定是”指令“!而且这个指令必须要能够接受 standard input 的数据才行,这样的指令才可以是为”管线命令“,例如 less, more, head, tail 等都是可以接受 standard input 的管线命令。至于例如 ls, cp, mv 等就不是管线命令了!因为 ls, cp, mv 并不会接受来自 stdin 的数据。 也就是说,管线命令主要有两个比较需要注意的地方:
1. 管线命令仅会处理 standard output,对于 standard error output 会予以忽略
2. 管线命令必须要能够接受来自前一个指令的数据成为 standard input 继续处理才行。
以下是一些常用的管线命令!这些命令对系统管理非常有帮助。
一、撷取命令: cut, grep
什么是撷取命令啊?说白了,就是将一段数据经过分析后,取出我们所想要的。或者是经由分析关键词,取得我们所想要的那一行! 不过,要注意的是,一般来说,撷取讯息通常是针对『一行一行』来分析的, 幵不是整篇讯息分析的,底下我们介绍两个很常用的讯息撷取命令:
cut
cut 就是『切』的意思,这个指令可以将一段讯息的某一段给他『切』出来~ 处理的讯息是以『行』为单位喔!底下我们就来谈一谈:
[root@www ~]# cut -d'分隔字符' -f fields <==用于有特定分隔字符
[root@www ~]# cut -c 字符区间 <==用于排列整齐的讯息
选项与参数:
-d :后面接分隔字符。与 -f 一起使用;
-f :依据 -d 的分隔字符将一段讯息分割成为数段,用 -f 取出第几段的意思;
-c :以字符 (characters) 的单位取出固定字符区间;
范例一:将 PATH 变量取出,我要找出第五个路径。
[root@www ~]# echo $PATH
/sbin:/usr/sbin:/usr/local/sbin:/root/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/games:/usr/lib/mit/bin:/usr/lib/mit/sbin
# 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
[root@www ~]# echo $PATH | cut -d ':' -f 5
/usr/local/bin
# 如同上面的数字显示,我们是以『 : 』作为分隔,因此会出现 /usr/local/bin
那么如果想要列出第 3 与第 5 呢?,就是这样:
[root@www ~]# echo $PATH | cut -d ':' -f 3,5
/usr/local/sbin:/usr/local/bin
范例二:将 export 输出的讯息,取得第 12 字符以后的所有字符串
[root@www ~]# export
declare -x COLORTERM="1"
declare -x CPU="x86_64"
declare -x CSHEDIT="emacs"
.....(其他省略).....
# 注意看,每个数据都是排列整齐的输出!如果我们不想要『 declare -x 』时,就得这么做:
[root@www ~]# export | cut -c 12-
COLORTERM="1"
CPU="x86_64"
CSHEDIT="emacs"
CVS_RSH="ssh"
.....(其他省略).....
# 知道怎么回事了吧?用 -c 可以处理比较具有格式的输出数据。 我们还可以指定某个范围的值,例如第 12-20 的字符,就是 cut -c 12-20 等等!
grep
刚刚的 cut 是将一行讯息当中,取出某部分我们想要的,而 grep 则是分析一行讯息, 若当中有我们所需要的信息,就将该行拿出来~简单的语法是这样的:
[root@www ~]# grep [-acinv] [--color=auto] '搜寻字符串' filename
选项与参数:
-a :将 binary 档案以 text 档案的方式搜寻数据
-c :计算找到 '搜寻字符串' 的次数
-i :忽略大小写的不同,所以大小写规为相同
-n :顺便输出行号
-v :反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行!
--color=auto :可以将找到的关键词部分加上颜色的显示喔!
范例一:将 last 当中,有出现 root 的那一行就取出来;
[root@www ~]# last | grep 'root'
范例二:与范例一相反,只要没有 root 的就取出!
[root@www ~]# last | grep -v 'root'
范例三:在 last 的输出讯息中,只要有 root 就取出,并且仅取第一栏
[root@www ~]# last | grep 'root' |cut -d ' ' -f 1
# 在取出 root 之后,利用上个指令 cut 的处理,就能够仅取得第一栏啰!
grep 是个很棒的指令喔!他支持的语法实在是太多了~用在正则表示法里头, 能够处理的数据实在是多的很。
二、排序命令: sort, uniq, wc
很多时候,我们都会去计算一次数据里头的相同型态的数据总数,举例来说, 使用 last 可以查得这个月份有登入主机者的身份。那么我可以针对每个使用者查出他们的总登入次数。 此时就得要排序与计算之类的指令来辅助了!底下我们介绍几个好用的排序与统计指令喔!
sort
sort 是可以帮我们进行排序,而且可以依据不同的数据型态来排序! 例如数字与文字的排序就不一样。
[root@www ~]# sort [-fbMnrtuk] [file or stdin]
选项与参数:
-f :忽略大小写的差异,例如 A 与 a 规为编码相同;
-b :忽略最前面的空格符部分;
-M :以月份的名字来排序,例如 JAN, DEC 等等的排序方法;
-n :使用『纯数字』进行排序(默认是以文字型态来排序的);
-r :反向排序;
-u :就是 uniq ,相同的数据中,仅出现一行代表;
-t :分隔符,预设是用 [tab] 键来分隔;
-k :以哪个区间 (field) 来进行排序的意思 范
例一:个人账号都记录在 /etc/passwd 下,请将账号进行排序。
[root@www ~]# cat /etc/passwd | sort
#sort 是预设『以第一个』数据来排序,而且默认是以『文字』型态来排序的喔!所以由 a 开始排到最后!
范例二:/etc/passwd 内容是以 : 来分隔的,我想以第三栏来排序,该如何?
[root@www ~]# cat /etc/passwd | sort -t ':' -k 3
# 如果是以文字型态来排序的话,原本就会是这样,想要使用数字排序:cat /etc/passwd | sort -t ':' -k 3 -n 这样才行啊!用那个 -n 来告知 sort 以数字来排序啊!
范例三:利用 last ,将输出的数据仅取账号,并加以排序
[root@www ~]# last | cut -d ' ' -f1 | sort
uniq
如果我排序完成了,想要将重复的资料仅列出一个显示,可以怎么做呢?
[root@www ~]# uniq [-ic]
选项与参数:
-i :忽略大小写字符的不同;
-c :进行计数
范例一:使用 last 将账号列出,仅取出账号栏,进行排序后仅取出一位;
[root@www ~]# last | cut -d ' ' -f1 | sort | uniq 或 last | cut -d ' ' -f1 | sort -u
wc
如果我想要知道 /etc/man.config 这个档案里面有多少字?多少行?多少字符的话, 可以怎么做呢?其实可以利用 wc 这个指令来达成喔!他可以帮我们计算输出的讯息的整体数据!
[root@www ~]# wc [-lwm]
选项与参数:
-l :仅列出行;
-w :仅列出多少字(英文单字);
-m :多少字符;
范例一:那个 /etc/man.config 里面到底有多少相关字、行、字符数?
[root@www ~]# cat /etc/man.config | wc
141 722 4617
# 输出的三个数字中,分别代表: 『行、字数、字符数』
这是相当有用的计算档案内容的一个工具组!举个例子来说, 当你要知道目前你的账号档案中有多少个账号时,就使用这个方法:
『 cat /etc/passwd | wc -l 』啦!因为 /etc/passwd 里头一行代表一个使用者呀! 所以知道行数就晓得有多少的账号在里头了!而如果要计算一个档案里头有多少个字符时,就使用 wc -c 这个选项吧!
三、关于减号 - 的用途
管线命令在 bash 的连续的处理程序中是相当重要的!另外,在 log file 的分析当中也是相当重要的一环, 所以请特别留意!另外,在管线命令当中,常常会使用到前一个到令的 stdout 作为这次的 stdin , 某些指令需要用到文件名 (例如 tar) 来进行处理时,该 stdin 与 stdout 可以利用减号 "-" 来替代, 举例来说:
[root@www ~]# tar -cvf - /home | tar -xvf -
上面这个例子是说:『我将 /home 里面的档案给他打包,但打包的数据不是记录到档案,而是传送到stdout; 经过管线后,将 tar -cvf - /home 传送给后面的 tar -xvf - 』。后面的这个 - 则是取用前一个指令的 stdout, 因此,我们就不需要使用 file 了!这是很常见的例子喔!