聲明: 我覺得今天的這篇文章就像一篇“工具”文而且很雞肋:歸納一些常用的管線命令和應用參數。適合有操作需求時,來查找能夠幫忙解決問題的指令和參數~
學習管線命令之前要先了解管道符|
,因爲管線命令使用的是|
這個界定符號,它和使用;
的連續下達命令“很像”(關於連續命令符號“;”,Linux 之 Bash -- 數據流重導向裏面剛學過,這裏不再提啦~)。爲了理解“|”,我們來舉個例子:
我想看一下 /etc
這個目錄下的文件列表,但是這個目錄裏的東西實在太多了,直接 ls -l /etc
打印到屏幕上滿屏都是,往回翻操作記錄都麻煩,所以可以使用ls -l /etc | less
,這樣ls指令輸出後的內容就能夠被less讀取,並且利用less的功能,我們就能夠前後翻動相關的信息了。這是ls -l /etc ; less
達不到的效果,因爲;
只起到下達命令的作用,而|
卻起到傳遞標準輸出STDOUT的作用,這是本質的區別。整體的管線命令可以用這個圖表表示:
使用時有兩個注意點:
- 管線命令僅會處理 standard output,對於 standard error output 會予以忽略
- 管線命令必須要能夠接受來自前一個指令的數據成爲 standard input 繼續處理才行
例如 ls,cp,mv這些不會接受stdin的命令,是不適合放在管道符|
後面的
1.擷(xie)取命令: cut,grep
用過cut的夥伴都知道,cut可以提取列,可是實際上,它和grep一樣都是針對文本“一行一行”來分析的,以cut -f 3 filename
爲例:cut文本第一行的第3段數據;cut文本第二行的第3段數據....直到文本的最後一行。最終,組成一列數據輸出出來。
1.1 cut
詳細聊聊cut
的應用
-
-d
後面接分隔字符,與-f
一起使用
eg:cut -d ':' -f 3,5 linux.txt
翻譯成人話就是 linux.txt以“:”爲分隔字符,幫我把第3段和第5段切出來 -
-f
後面接數字,取出第幾段的意思 -
-c
後面接數字
以字符(characters)的單位取出固定字符區間
eg:cut -c 1-8 linux.txt
翻譯成人話 幫我把linux.txt中的,每一行的,第1-8個字符切出來(如果是8-
,意即把第8個之後的字符都切出來)
1.2 grep
grep同樣是一行一行得分析,它的做事風格很豪爽:如果當中有我想要的信息,就把這一整行都拽出來
grep支持的語法很多,還支持 正規表示法 ,可惜panda還沒把正規表示法學通,在這裏就只簡單介紹幾個參數,等到後面再及時更新
-
-c
計算“搜尋字符串”的次數
eg:grep -c time linux.txt
翻譯成人話 計算time在linux.txt中出現的次數 -
-i
忽略大小寫來擷取文本行
eg:grep -i AB linux.txt
翻譯成人話 把linux.txt文本中含有"ab or AB or Ab or aB"的文本行拽出來 -
-n
順便輸出行號 -
-v
反向選擇,顯示沒有“搜索字符串”內容的那一行
2.排序命令 sort,wc,uniq
2.1 sort
sort的大特點:可以依據不同的數據型態來排序
-
-f
忽略大小寫的差異 -
-b
忽略最前面的空格符部分 -
-M
以月份的名字來排序 -
-n
使用純數字進行排序(默認是以文字型態來排序的) -
-r
反向排序 -
-u
相同的數據中,僅出現一行代表(uniq) -
-t
指定分隔符(預設是用tab鍵) 和 cut 中的-d
參數作用類似 -
-k
以哪個區間排序
eg:sort -k 3 linux.txt
以linux.txt中的第3列進行排序
2.2 uniq
用於排序完成後,將重複的資料僅列出一個顯示,它的一些參數:
-
-i
忽略大小寫字符的不同 -
-c
進行計數
2.3 wc 統計行數、字數、字符數
-
-l
僅列出行 -
-w
僅列出多少字(英文單字) -
-m
多少字符
3.雙向重導向 tee
tee的功能其實很簡單,可以讓standard output轉存一份到文件內並將同樣的數據繼續送到屏幕去處理
舉個例子來認識它:
ls -l | tee list.txt | less
翻譯成人話:查看當前目錄並且將目錄內容保存到 list.txt中看到了吧,這裏tee把standard ourtput做了雙向輸出:一個走向
list.txt
;一個走向 屏幕,不過我這裏用less
來查看信息除此之外,記憶一個tee的參數:
-
-a
以累加的方式,將數據加入file當中(類似>>
)
4.字符轉換命令:tr,col,join,paste,expand
4.1 tr(刪除或替換文字訊息)
刪除一段訊息中的文字;或者進行文字訊息的替換
注意:tr只能從標準輸入中讀取數據,因此使用tr時,
1.要麼通過<
將輸入文件重定向到標準輸入;
2.要麼通過管道符|
讀入數據
-
tr '[a-z]' '[A-Z]'
將所有的小寫變成大寫
eg:tr '[a-z]' '[A-Z]' < list.txt
將list.txt 中的所有小寫字母轉換成大寫輸出到屏幕 -
-d
刪除訊息當中的字符串
eg:cat /etc/passwd | tr -d ':'
/etc/passwd 輸出的訊息中,將“:”刪除 -
-s
取代掉重複的字符
4.2 col(用對等的空格鍵取代tab鍵)
最常用的操作:通過使用參數-x
,將[tab]按鍵取代成爲對應的 相同長度的 空格鍵
eg:cat -A list.txt
(如果list.txt 中有tab鍵,就會看到很多^I的符號;cat -A
可以顯示出所有的特殊按鍵)
再試試cat list.txt | col -x | cat -A
這樣打印到屏幕的輸出就美觀多了
不要光說不做哦~just do it ~
4.3 join(根據相關性合併文件)
join這個小命令只能處理2個文件之間的數據:兩個文件當中,有“相同數據”的那一行,纔將他們加在一起
例如 /etc/passwd 和 /etc/shadow這兩個文件(先看他們的文本特點):
可以看到,這兩個文本的分隔符都是
:
,同時第一個字段的內容都相同(都是 root,bin,daemon),如果我們想要把兩個文本中不同的數據合在一起,就可以使用join將他們變成這個樣子:join -t ':' /etc/passwd /etc/shadow | head -n 3
認識join的一些參數:join [-ti12] file1 file2
-
-t
: 用來指定分隔符
👆join -t ':' /etc/passwd /etc/shadow | head -n 3
中就是讓兩個文件合併後以':'分隔。如果不設置的話,默認以空格分隔數據 -
-i
: 忽略大小寫的差異 -
-1
代表第一個文件-2
代表第二個文件
這兩個數字分別指代對應文件要用哪個字段來分析進行整合
eg:join -1 2 a.txt -2 3 b.txt
翻譯成人話 將a.txt的第2個字段和b.txt的第3個字段整合在一起
注意:插播一下使用join時的注意點
1.需要處理的文件以防順序錯亂,最好排序並去重後再join;
2.指定要整合的字段要相同啊!
而剛開始瞭解join時,沒有數字參數的這個指令是怎麼執行的?join -t ':' /etc/passwd /etc/shadow | head -n 3
實際上,👆它只是進行了參數的省略而已,linux默認以兩個文件的第1個字段進行分析和整合,完整的它應該是這個樣子join -t ':' -1 1 /etc/passwd -2 1 /etc/shadow | head -n 3
怎麼樣?是不是有點頭暈?哈哈,記住就好啦~
總之,join在處理兩個相關的數據文件時是非常有幫助的,例如/etc/passwd和/etc/shadow以賬號爲相關性,而/etc/passwd和/ec/group以所謂的GID(賬號的數字定義)爲相關性,通過join可以把這些有用的數據放在一起。
4.4 paste(簡單粗暴得合併文件)
和join作用類似,也是將兩個文件的數據貼在一起,但是它的方式簡單粗暴,不會去比較內容是否相關,而是直接將行號相同的字段拼在一起,默認以tab鍵分隔。
工作模式 paste [-d] file1 file2
-
-d
後面可以接分隔字符,預設是tab鍵
eg:paste /etc/passwd /etc/shadow
-
-
如果file部分寫成-
,表示來自standard input的資料的意思(以後用到再詳細解釋)
4.5 expand(用空格取代tab鍵)
還記得上面提到的col -x
嗎,它可以將tab鍵取代爲相同長度的空格鍵。expand和它作用類似,不過expand可以自由設定tab鍵取代成空格鍵的個數,所以功能是比col -x
更強大的。
常見的工作模式 expand [-t] file
-
-t
後面可以接數字
eg:expand -t 6 a.txt | cat -A
將a.txt中的tab鍵以1:6的個數比例轉換成空格鍵,並且打印到屏幕(cat -A看一下文件內的所有特殊符號)
小插曲:** 如果我想讓空格鍵轉成tab鍵怎麼辦? **
答案:使用unexpand
-
-a
除了單詞前作爲單詞分隔的空格外,所有空格都會被轉換 -
--first-only
僅轉換每行開頭的空格 -
-t
指定一個tab鍵佔幾個字符位(默認8)
5. 分區命令:split
split可以根據文件大小或行數來分區,從而將大文件分成小文件。
(在我們常用的windows裏面可是個大問題啊,而進入linux,我們可以很方便得使用split啦~)
常用工作模式: split [-bl] file PREFIX
常用選項和參數
-
-b
後面可接欲分區成的文件大小(可加單位,eg: b,k,m等) -
-l
以行數來進行分區
PREFIX
代表前導符的意思,可作爲分區文件的前導文字
eg: - 按文件大小split
如果 a.txt 是一個800+kb的大文件,可以通過split分成3個最大爲300kb 的文件。 指令:split -b 300k a.txt
- 按文件行數split
如果 a.txt 是一個100+ 行的大文件,可以通過split分成6個最大爲20行的文件。 指令 :split -l 20 a.txt
6.參數代換:xargs
xargs 可以用來產生某個指令的參數,可讀入stdin的數據,並且以空格符或斷行字符作爲分辨,將stdin的資料分隔成arguments(參數)。
xargs聽起來很嚇人,難理解也是因爲實踐與想象有差距。如果學着應用它,就會發現,它其實也是很簡單的一個命令,don't panic~
常見工作模式:xargs [-0epn] command
選項與參數:
-
-0
(數字0不是字母O啊~)
如果輸入的stdin含有特殊字符,例如. \ \.
空格鍵等字符時,這個-0參數可以將他還原成一般字符。這個參數可以用於特殊狀態。 -
-e
這個是EOF (end of file) 的意思,後面可以接一個字符串,當xargs分析到這個字符串時,就會停止繼續工作。 -
-p
在執行每個指令的argument時,都會詢問使用者的意思 -
-n
後面接次數,每次command指令執行時,要使用幾個參數的意思
實踐前熱身(可以試着在自己的集羣上操作)
下面分幾步介紹
id
,同時襯托一下xargs
存在的“魅力”!
id
指令可以查詢用戶的UID/GID等信息 eg:id root
- step 1 認識
id
只接受一個參數的侷限性
id $(cut -d ':' -f 1 /etc/passwd | head -n 3)
翻譯成人話: 將/etc/passwd中的第一列的前三行取出來,並且使用id指令查看信息
這裏通過$(cut -d ':' -f 1 /etc/passwd | head -n 3)
預先取得了參數,但是因爲id只能接受一個參數,因此它會在linux系統裏報錯。
-step 2 認識id
並不是管線命令的侷限性
cut -d ':' -f 1 /etc/passwd | head -n 3 | id
最終你會發現,你查了自己!因爲id
不是管線命令,它是沒有辦法接收|
前面的信息的。因此cut -d ':' -f 1 /etc/passwd | head -n 3 | id
的執行效果 就等於 直接在linux命令行中輸入id
所執行的結果。
這可腫麼辦? xargs來了就有了辦法~
-
xargs -n
cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id
就可以順利得獲得相應用戶的詳細信息,把它翻譯成人話就是:將/etc/passwd的第一列的前三行提出來然後通過xargs將此三行內容轉換成指令id的參數(考慮到id只能一個一個得接收參數,因此使用了-n 1
使3個參數一個一個得傳遞到達) -
xargs -p
cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -p -n 1 id
這裏增加了-p
選項,則在使用過程中,被詢問到每個指令是否執行! -
xargs -e
cut -d ':' -f 1 /etc/passwd | xargs -e'sync' -n 1 id
在我們下達 -e'sync'後,在分析到sync這個字符串時,後面的stdin內容就會被xargs捨棄掉了