Linux系统运维/Bash/5-6-管道命令

管线命令 (pipe)

 [root@www ~]# ls -al /etc | less

这个管线命令『 | 』仅能处理经由前面一个命令传来的正确信息,也就是 standard output 的信息,对于 stdandard error 并没有直接处理的能力。那么整体的管线命令可以使用下图表示:


图 6.1.1、 管线命令的处理示意图

也就是说,管线命令主要有两个比较需要注意的地方:

管线命令仅会处理 standard output,对于 standard error output 会予以忽略

管线命令必须要能够接受来自前一个命令的数据成为 standard input 继续处理才行。

撷取命令: cut, grep

cut

撷取命令就是将一段数据经过分析后,取出我们所想要的。撷取信息通常是针对『一行一行』来分析的, cut 在处理多空格相连的数据时,可能会比较吃力一点

其语法格式为:cut  [-bn] [file] cut [-c] [file]    cut [-df] [file]

主要参数
-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
-c :以字符为单位进行分割。
-d :自定义分隔符,默认为制表符。
-f  :与-d一起使用,指定显示哪个区域。
-n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由-b 标志的 List 参数指示的
范围之内,该字符将被写出;否则,该字符将被排除。

grep

刚刚的 cut 是将一行信息当中,取出某部分我们想要的,而 grep 则是分析一行信息, grep 可以解析一行文字,取得关键词,若该行有存在关键词,就会整行列出来!

语法如下:

grep [-acinv] [--color=auto] '搜寻字符串' filename

选项与参数:

-a :将 binary 文件以 text 文件的方式搜寻数据

-c :计算找到 '搜寻字符串' 的次数

-i :忽略大小写的不同,所以大小写视为相同

-n :顺便输出行号

-v :反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行!

--color=auto :可以将找到的关键词部分加上颜色的显示喔!

sort

sort 是很有趣的命令,他可以帮我们进行排序,而且可以依据不同的数据型态来排序喔! 例如数字与文字的排序就不一样。此外,排序的字符与语系的编码有关,因此, 如果您需要排序时,建议使用 LANG=C 来让语系统一,数据排序比较好一些。

[root@www ~]# sort [-fbMnrtuk] [file orstdin]

选项与参数:

-f  :忽略大小写的差异,例如 A 与 a 视为编码相同;

-b  :忽略最前面的空格符部分;

-M  :以月份的名字来排序,例如 JAN, DEC 等等的排序方法;

-n  :使用『纯数字』进行排序(默认是以文字型态来排序的);

-r  :反向排序;

-u  :就是 uniq ,相同的数据中,仅出现一行代表;

-t  :分隔符,默认是用 [tab] 键来分隔;

-k  :以那个区间 (field) 来进行排序的意思

uniq

[root@www ~]# uniq [-ic]

选项与参数:

-i  :忽略大小写字符的不同;

-c  :进行计数

使用 last 将账号列出,仅取出账号栏,进行排序后仅取出一位;

[root@www ~]# last | cut -d ' ' -f1 | sort| uniq

承上题,如果我还想要知道每个人的登陆总次数呢?

[root@www ~]# last | cut -d ' ' -f1 | sort| uniq -c

     1

    12 reboot

    41 root

     1 wtmp

wc

知道文件里面有多少字?多少行?多少字符的话

[root@www ~]# wc [-lwm]

选项与参数:

-l  :仅列出行;

-w  :仅列出多少字(英文单字);

-m  :多少字符;

双向重导向: tee

tee 的工作流程示意图:

tee 会同时将数据流分送到文件去与屏幕 (screen);而输出到屏幕的,其实就是 stdout ;

tr

 

[root@www ~]# tr [-ds] SET1 ...

选项与参数:

-d  :删除信息当中的 SET1 这个字符串;

-s  :取代掉重复的字符!

 

将 last 输出的信息中,所有的小写变成大写字符:

[root@www ~]# last | tr '[a-z]' '[A-Z]'

# 事实上,没有加上单引号也是可以运行的,如:『 last | tr [a-z] [A-Z] 』

 

将 /etc/passwd 输出的信息中,将冒号 (:) 删除

[root@www ~]# cat /etc/passwd | tr -d ':'

 

将 /etc/passwd 转存成 dos 断行到 /root/passwd 中,再将 ^M 符号删除

[root@www ~]# cp /etc/passwd /root/passwd&& unix2dos /root/passwd

[root@www ~]# file /etc/passwd /root/passwd

/etc/passwd:  ASCII text

/root/passwd: ASCII text, with CRLF lineterminators <==就是 DOS 断行

[root@www ~]# cat /root/passwd | tr -d '\r'> /root/passwd.linux

# 那个 \r 指的是 DOS 的断行字符,关于更多的字符,请参考 man tr

[root@www ~]# ll /etc/passwd /root/passwd*

-rw-r--r-- 1 root root 1986 Feb  6 17:55 /etc/passwd

-rw-r--r-- 1 root root 2030 Feb  7 15:55 /root/passwd

-rw-r--r-- 1 root root 1986 Feb  7 15:57 /root/passwd.linux

# 处理过后,发现文件大小与原本的 /etc/passwd 就一致了!

col

[root@www ~]# col [-xb]

选项与参数:

-x  :将 tab 键转换成对等的空格键

-b  :在文字内有反斜杠 (/) 时,仅保留反斜杠最后接的那个字符

利用 cat -A 显示出所有特殊按键,最后以 col 将 [tab] 转成空白

[root@www ~]# cat -A /etc/man.config  <==此时会看到很多 ^I 的符号,那就是 tab

[root@www ~]# cat /etc/man.config | col -x| cat -A | more

# 嘿嘿!如此一来, [tab] 按键会被取代成为空格键,输出就美观多了!

将 col 的 man page 转存成为 /root/col.man 的纯文本

[root@www ~]# man col | col -b >/root/col.man

 

join

 

[root@www ~]# join [-ti12] file1 file2

选项与参数:

-t  :join 默认以空格符分隔数据,并且比对『第一个字段』的数据,

     如果两个文件相同,则将两笔数据联成一行,且第一个字段放在第一个!

-i  :忽略大小写的差异;

-1  :这个是数字的 1 ,代表『第一个文件要用那个字段来分析』的意思;

-2  :代表『第二个文件要用那个字段来分析』的意思。

 

paste

paste 就直接『将两行贴在一起,且中间以 [tab] 键隔开』而已!简单的使用方法:

 

[root@www ~]# paste [-d] file1 file2

选项与参数:

-d  :后面可以接分隔字符。默认是以 [tab] 来分隔的!

-   :如果 file 部分写成 - ,表示来自 standardinput 的数据的意思。

 

先将 /etc/group 读出(用 cat),然后与范例一贴上一起!且仅取出前三行

[root@www ~]# cat /etc/group|paste/etc/passwd /etc/shadow -|head -n 3

# 这个例子的重点在那个 - 的使用!那玩意儿常常代表 stdin喔!

 

expand

 

这玩意儿就是在将 [tab] 按键转成空格键啦~可以这样玩:

 

[root@www ~]# expand [-t] file

选项与参数:

-t  :后面可以接数字。一般来说,一个 tab 按键可以用 8 个空格键取代。

     我们也可以自行定义一个 [tab] 按键代表多少个字符呢!

 

[root@www ~]# grep '^MANPATH'/etc/man.config | head -n 3

[root@www ~]# grep '^MANPATH'/etc/man.config | head -n 3 |cat -A

[root@www ~]# grep '^MANPATH'/etc/man.config | head -n 3 | \

> expand -t 6 - | cat -A

 

expand 也是挺好玩的~他会自动将[tab]转成空格键

unexpand 这个将空白转成[tab]的命令功能啊!

 

小标题的图示分割命令: split

他可以帮你将一个大文件,依据文件大小或行数来分割,就可以将大文件分割成为小文件了

[root@www ~]# split [-bl] file PREFIX

选项与参数:

-b  :后面可接欲分割成的文件大小,可加单位,例如 b, k, m 等;

-l  :以行数来进行分割。

PREFIX :代表前导符的意思,可作为分割文件的前导文字。

 

/etc/termcap 有七百多K,若想要分成 300K 一个文件时?

[root@www ~]# cd /tmp; split -b 300k/etc/termcap termcap

[root@www tmp]# ll -k termcap*

-rw-r--r-- 1 root root 300 Feb  7 16:39 termcapaa

-rw-r--r-- 1 root root 300 Feb  7 16:39 termcapab

-rw-r--r-- 1 root root 189 Feb  7 16:39 termcapac

# 那个档名可以随意取的啦!我们只要写上前导文字,小文件就会以

# xxxaa, xxxab, xxxac 等方式来创建小文件的!

 

如何将上面的三个小文件合成一个文件,档名为 termcapback

[root@www tmp]# cat termcap* >>termcapback

# 很简单吧?就用数据流重导向就好啦!简单!

 

使用 ls -al / 输出的信息中,每十行记录成一个文件

[root@www tmp]# ls -al / | split -l 10 -lsroot

[root@www tmp]# wc -l lsroot*

  10lsrootaa

  10lsrootab

   6lsrootac

  26total

# 重点在那个 -啦!一般来说,如果需要stdout/stdin时,但偏偏又没有文件,

# 有的只是 -时,那么那个 - 就会被当成 stdin stdout

 

参数代换: xargs

在产生某个命令的参数的意思!xargs 可以读入 stdin 的数据,并且以空格符或断行字符作为分辨,将 stdin 的数据分隔成为 arguments 。 因为是以空格符作为分隔,所以,如果有一些档名或者是其他意义的名词内含有空格符的时候, xargs 可能就会误判了~他的用法其实也还满简单的!就来看一看先!

[root@www ~]# xargs [-0epn] command

选项与参数:

-0  :如果输入的 stdin 含有特殊字符,例如 `, \, 空格键等等字符时,这个 -0 参数

     可以将他还原成一般字符。这个参数可以用于特殊状态喔!

-e  :这个是 EOF (end of file) 的意思。后面可以接一个字符串,当 xargs 分析到

     这个字符串时,就会停止继续工作!

-p  :在运行每个命令的 argument 时,都会询问使用者的意思;

-n  :后面接次数,每次 command 命令运行时,要使用几个参数的意思。看范例三。

当 xargs 后面没有接任何的命令时,默认是以 echo 来进行输出喔!

 

范例一:将 /etc/passwd 内的第一栏取出,仅取三行,使用 finger 这个命令将每个

       账号内容秀出来

[root@www ~]# cut -d':' -f1 /etc/passwd|head -n 3| xargs finger

Login: root                             Name: root

Directory: /root                        Shell: /bin/bash

Never logged in.

No mail.

No Plan.

......底下省略.....

# 由 finger account 可以取得该账号的相关说明内容,例如上面的输出就是 finger root

# 后的结果。在这个例子当中,我们利用 cut 取出账号名称,用 head 取出三个账号,

# 最后则是由 xargs 将三个账号的名称变成 finger 后面需要的参数!

 

范例五:找出 /sbin 底下具有特殊权限的档名,并使用 ls -l 列出详细属性

[root@www ~]# find /sbin -perm +7000 | ls-l

# 结果竟然仅有列出 root 所在目录下的文件!这不是我们要的!

# 因为 ll (ls)并不是管线命令的原因啊!

[root@www ~]# find /sbin -perm +7000 |xargs ls -l

-rwsr-xr-x 1 root root 70420 May 25  2008 /sbin/mount.nfs

-rwsr-xr-x 1 root root 70424 May 25  2008 /sbin/mount.nfs4

-rwxr-sr-x 1 root root  5920 Jun 15 2008 /sbin/netreport

....(底下省略)....

小标题的图示关于减号 - 的用途

管线命令在 bash 的连续的处理程序中是相当重要的,在 log file 的分析当中也是相当重要的一环;管线命令当中,常常会使用到前一个命令的 stdout 作为这次的 stdin ,某些命令需要用到文件名 (例如 tar) 来进行处理时,该 stdin 与 stdout 可以利用减号 "-" 来替代, 举例来说:

 

[root@www ~]# tar -cvf - /home | tar -xvf -

 

你可能感兴趣的:(初级运维)