學習管道之前我們先了解一下linux的命令執(zhí)行順序
命令執(zhí)行順序控制
通常情況下,我們在終端只能執(zhí)行一條命令,然后按下回車執(zhí)行,那么如何執(zhí)行多條命令呢?
- 順序執(zhí)行多條命令:command1;command2;command3;
簡單的順序指令可以通過;來實現(xiàn)- 有條件的執(zhí)行多條命令:which command1 && command2 || command3
&& : 如果前一條命令執(zhí)行成功則執(zhí)行下一條命令,如果command1執(zhí)行成功(返回0),則執(zhí)行command2
|| :與&&命令相反,執(zhí)行不成功時執(zhí)行這個命令$?: 存儲上一次命令的返回結果
栗子:
$ which git>/dev/null && git --help // 如果存在git命令,執(zhí)行git --help命令
$ echo $?
管道命令
管道是一種通信機制,通常用于進程間的通信(也可通過socket進行網絡通信),它表現(xiàn)出來的形式將前面每一個進程的輸出(stdout)直接作為下一個進程的輸入(stdin)。
管道命令使用|作為界定符號,管道命令與上面說的連續(xù)執(zhí)行命令不一樣。
管道命令僅能處理standard output,對于standard error output會予以忽略。
less,more,head,tail...都是可以接受standard input的命令,所以他們是管道命令
ls,cp,mv并不會接受standard input的命令,所以他們就不是管道命令了。管道命令必須要能夠接受來自前一個命令的數據成為standard input繼續(xù)處理才行。
第一個管道命令
$ ls -al /etc | less
通過管道將ls -al的輸出作為 下一個命令less的輸入,方便瀏覽。

選取命令:cut.grep
- cut:從某一行信息中取出某部分我們想要的信息。
cut -d '分隔字符' -f field // 用于分隔字符
cut -c 字符范圍
[參數說明]
-d : 后面接分隔字符,通常與 -f 一起使用
-f : 根據-d 將信息分隔成數段,-f 后接數字 表示取出第幾段
-c : 以字符為單位取出固定字符區(qū)間的信息
栗子1:
打印/etc/passwd文件中以:為分隔符的第1個字段和第6個字段分別表示用戶名和家目錄
[root@izuf6i29flb2df231kt91hz /]# cat etc/passwd | cut -d ':' -f 1,6
root:/root
bin:/bin
daemon:/sbin
adm:/var/adm
lp:/var/spool/lpd
...
栗子2:
打印/etc/passwd文件中每一行的前10個字符:
[root@izuf6i29flb2df231kt91hz /]# cat /etc/passwd | cut -c 1-10
root:x:0:0
bin:x:1:1:
daemon:x:2
adm:x:3:4:
lp:x:4:7:l
...
ps:cut在處理多空格相連的數據時,比較吃力。
- grep:分析一行信息,如果其中有我們需要的信息,就將該行拿出來
grep [-acinv] [--color=auto] '查找字符串' filename
[參數]
-a : 將binary文件以text文件的方式查找數據
-c : 計算找到 '查找字符串'的次數
-i : 忽略大小寫的不同
-n : 輸出行號
-v : 反向選擇,顯示沒有查找內容的行
--color=auto : 將找到的關鍵字部分加上顏色顯示
栗子3:
取出含有 fanco 的/etc/passwd文件的行
[root@izuf6i29flb2df231kt91hz /]# cat etc/passwd | grep -n -c 'fanco'
1
[root@izuf6i29flb2df231kt91hz /]# cat etc/passwd | grep -n 'fanco'
23:fanco:x:1001:1001::/home/fanco:/bin/bash
[root@izuf6i29flb2df231kt91hz /]# cat etc/passwd | grep -n -v 'fanco'
1:root:x:0:0:root:/root:/bin/bash
2:bin:x:1:1:bin:/bin:/sbin/nologin
3:daemon:x:2:2:daemon:/sbin:/sbin/nologin
4:adm:x:3:4:adm:/var/adm:/sbin/nologin
5:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
...

排序命令:sort,wc,uniq
sort
sort [-fbMnrtuk] [file or stdin]
[參數]
-f :忽略大小寫的差異,例如A 與a 視為編碼相同
-b :忽略最前面的空格部分
-M :以月份的名字來排序,例如JAN, DEC 等等的排序方法
-n :使用『純數字』進行排序默認是以文字型態(tài)來排序的)
-r :反向排序
-u :就是uniq ,相同的資料中,僅出現(xiàn)一行代表
-t :分隔符號,預設是用[tab] 鍵來分隔
-k :以那個區(qū)間(field) 來進行排序的意思
栗子4:
對/etc/passwd的賬號進行排序
[root@izuf6i29flb2df231kt91hz /]# cat /etc/passwd | sort
adm:x:3:4:adm:/var/adm:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
...
通過/etc/passwd 第5列來進行排序
[root@izuf6i29flb2df231kt91hz /]# cat etc/passwd | sort -t ':' -k 3
root:x:0:0:root:/root:/bin/bash
fanco:x:1001:1001::/home/fanco:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
這里排序還是按照文字進行排序的,切換成數字排序
[root@izuf6i29flb2df231kt91hz /]# cat etc/passwd | sort -t ':' -k 3 -n
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
- uniq
uniq [-ic]
[參數]
-i :忽略大小寫的不同
-c :進行計數
栗子5
使用 last 取出歷史登錄信息的賬號,排序,去重
[root@izuf6i29flb2df231kt91hz /]# last | cut -d ' ' -f 1 | sort | uniq -c
1
7 reboot
19 root
1 wtmp
- wc
wc [-lwm]
[參數]
-l :僅列出行
-w :僅列出多少字(英文單字)
-m :多少字符
栗子6
查看etc/passwd中有多少賬號
[root@izuf6i29flb2df231kt91hz /]# cat /etc/passwd | wc -l
23
計算最近登錄系統(tǒng)的人次
[root@izuf6i29flb2df231kt91hz /]# last | grep [a-zA-Z] | grep -v 'wtmp' | wc -l
2
查看某個文件的行數 字數 字符數
[root@izuf6i29flb2df231kt91hz /]# cat etc/passwd | wc
23 32 997
雙向重定向命令:tee
-
tee:在數據流的處理過程中將某段信息保存下來,使其既能輸出到屏幕又能保存到某一個文件中。
tee的工作流程.png
tee [-a] file
[參數]
-a : 以累加的方式,將數據加入file中
栗子7
查詢最近用戶登錄情況,并將其保存到文件中
[root@izuf6i29flb2df231kt91hz /]# last | tee info | cut -d ' ' -f 1
root
...
[root@izuf6i29flb2df231kt91hz /]# less info
root pts/0 112.28.181.159 Sun Jul 1 14:28 still logged in
root pts/0 112.28.181.159 Sun Jul 1 14:24 - 14:27 (00:03)
root pts/0 112.28.181.159 Sun Jul 1 13:19 - 14:24 (01:04)
root tty1 Sun Jul 1 12:46 still logged in
如果tee后接的文件已存在,內容會被覆蓋掉,加上 -a參數則會累加
字符轉換命令:tr,col,join,paste,expand
- tr:用來刪除一段信息當中的文字,或者進行文字信息得替換
tr [-ds] set
[參數]
-d : 刪除信息當中的set1這個字符串
-s : 替換掉重復的字符
栗子8
將上一步生成的info 文件刪除掉所有的 root
刪除前
[root@izuf6i29flb2df231kt91hz /]# cat info
root pts/0 112.28.180.86 Thu May 10 18:01 - 18:12 (00:11)
reboot system boot 3.10.0-693.2.2.e Fri May 11 02:00 - 16:31 (51+14:30)
刪除后
[root@izuf6i29flb2df231kt91hz /]# cat info | tr -d 'root'
ps/0 112.28.180.86 Thu May 10 18:01 - 18:12 (00:11)
eb sysem b 3.10.0-693.2.2.e Fi May 11 02:00 - 16:31 (51+14:30)
刪除時并不是只刪除連續(xù)的字符,reboot也被刪除掉了root部分
除去dos文件留下來的^M符號
$ cat /root/passwd | tr -d '\r' > /root/passwd.linux
^M可以用\r替代
- col
col [-xb]
[參數]
-x : 將tab鍵換成對等的空格鍵
-b : 在文字內有反斜杠(/)時,僅保留反斜杠最后接的那個字符

栗子9
將上圖中的^I換成空格鍵
[root@izuf6i29flb2df231kt91hz /]# cat info | col -x | cat -A | more
root pts/0 112.28.181.159 Sun Jul 1 14:28 still logged in$
col經常被用于將man page轉存為純文本文件
- join:主要講兩個文件有相同數據的一行,相同字段放在前面
join [-ti12] file1 file2
[參數]
-t : join 默認以空格符分隔數據,并且對比第一個字段的數據 ,如果兩個文件相同,則將兩條數據連成一行
-i : 忽略大小寫的差異
-1 : 說明第一個文件通過那個字段來進行分析
-2 : 說明第二個文件通過那個字段來分析
栗子10
將/etc/passwd 與 /etc/shadow 相關數據整合成一列
[root@izuf6i29flb2df231kt91hz /]# head -3 /etc/passwd /etc/shadow
==> /etc/passwd <==
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
==> /etc/shadow <==
root:$6$RNGEziM7$2e/EJd3hThS8TMqHSgDIfeDf7dJUG1dbJ0ik1goybGYmLGZL.sHNv1Ltb4.1HUksxTI0Cs3PJw5g/YirSImKg1:17643:0:99999:7:::
bin:*:17110:0:99999:7:::
daemon:*:17110:0:99999:7:::
[root@izuf6i29flb2df231kt91hz /]# join -t ':' /etc/passwd /etc/shadow
root:x:0:0:root:/root:/bin/bash:$6$RNGEziM7$2e/EJd3hThS8TMqHSgDIfeDf7dJUG1dbJ0ik1goybGYmLGZL.sHNv1Ltb4.1HUksxTI0Cs3PJw5g/YirSImKg1:17643:0:99999:7:::
bin:x:1:1:bin:/bin:/sbin/nologin:*:17110:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:17110:0:99999:7:::
將etc/passwd 按:分隔的第4個字段 與 etc/group的第3個字段 比較,如果相同,則將他兩同行數據放在一起
[root@izuf6i29flb2df231kt91hz /]# join -t ':' -1 4 /etc/passwd -2 3 /etc/group
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:
4:adm:x:3:adm:/var/adm:/sbin/nologin:adm:x:
join: /etc/passwd:6: is not sorted: sync:x:5:0:sync:/sbin:/bin/sync
7:lp:x:4:lp:/var/spool/lpd:/sbin/nologin:lp:x:
- paste:直接將兩個文件兩行貼在一起,中間以[tab]鍵隔開
paste [-d] file1 file2
[ 參數]
-d : 后面可以接分隔字符,默認以[tab]來分隔的
- : 如果file部分寫成-,表示接受standard input數據的意思
栗子11
[root@izuf6i29flb2df231kt91hz /]# paste info info2
root pts/0 112.28.181.159 Sun Jul 1 14:28 still logged in root pts/0 112.28.181.159 Sun Jul 1 14:28 still logged in
root pts/0 112.28.181.159 Sun Jul 1 14:24 - 14:27 (00:03) root pts/0 112.28.181.159 Sun Jul 1 14:24 - 14:27 (00:03)
root pts/0 112.28.181.159 Sun Jul 1 13:19 - 14:24 (01:04) root pts/0 112.28.181.159 Sun Jul 1 13:19 - 14:24 (01:04)
- *expand:把tab鍵轉為空格鍵
expand [-t] file
[參數]
`` -t : 后面接數字,一般,一個tab可以用8個空格代替,可以自行定義代表幾個空格
栗子12
[root@izuf6i29flb2df231kt91hz /]# cat info | expand -3 info
root pts/0 112.28.181.159 Sun Jul 1 14:28 still logged in
root pts/0 112.28.181.159 Sun Jul 1 14:24 - 14:27 (00:03)
root pts/0 112.28.181.159 Sun Jul 1 13:19 - 14:24 (01:04)
root tty1 Sun Jul 1 12:46 still logged in
切割命令:split
split:顧名思義,講一個大文件依據文件大小或行數切割成為小文件
split [-bl] file prefix
[參數]
-b : 后面可接欲切割文件的大小,可加單位,例如b,k,m等
-l : 以行數來進行切割
PREFIX : 代表前導符,可作為切割文件的前導文字
栗子
$ split -b 300K /etc/passwd
將ls -al輸出文件 按10行分成一個新的文件
[root@izuf6i29flb2df231kt91hz /]# ls -al / | split -l 10 - lsrrot
[root@izuf6i29flb2df231kt91hz /]# ls
b boot dev home info2 lib64 lsrrotaa lsrrotac mnt opt root sbin sys usr
bin c etc info lib lost+found lsrrotab media n proc run srv tmp var
[root@izuf6i29flb2df231kt91hz /]# cd /
[root@izuf6i29flb2df231kt91hz /]# ls
b boot dev home info2 lib64 lsrrotaa lsrrotac mnt opt root sbin sys usr
bin c etc info lib lost+found lsrrotab media n proc run srv tmp var
[root@izuf6i29flb2df231kt91hz /]# wc -l lsrrot*
10 lsrrotaa
10 lsrrotab
9 lsrrotac
29 total
