Linux基礎學習-管道命令

就如同前面所說的, bash 命令執行的時候有輸出的數據會出現! 那麼如果這羣數據必需要經過幾道手續之後才能得到我們所想要的格式,應該如何來設定? 這就牽涉到管線命令的問題了 (pipe) ,管線命令使用的是『 | 』這個界定符號! 另外,管線命令與『連續下達命令』是不一樣的呦! 這點底下我們會再說明。底下我們先舉一個例子來說明一下簡單的管線命令。

  假設我們想要知道 /etc/ 底下有多少檔案,那麼可以利用 ls /etc 來查閱,不過, 因爲 /etc 底下的檔案太多,導致一口氣就將屏幕塞滿了~不知道前面輸出的內容是啥?此時,我們可以透過 less 指令的協助,利用:

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


嘿嘿!如此一來,使用 ls 指令輸出後的內容,就能夠被 less 讀取, 並且利用 less 的功能,我們就能夠前後翻動相關的信息了!很方便是吧?呵呵! 我們就來了解一下這個管線命令『 | 』的用途吧! 這個管線命令『 | 』僅能處理經由前面一個指令傳來的正確信息,也就是 standard output ( STDOUT ) 的信息,對於 stdandard error 並沒有直接處理的能力,請記得。
 

每個管線的前後部分都是『指令』呢!而後一個指令的輸入乃是由前一個指令的輸出而來的! 不過,要注意的是,在 Linux 的環境中,很多的訊息處理都是以『行』爲單位~ 也就是以是否具有 [Enter] 標誌 (CR) 來作爲一段處理的依據喔! 底下我們來談一談一些基本的管線命令指令介紹:






擷取命令: cut, grep


什麼是擷取命令啊?說穿了,就是將一段數據經過分析後,取出我們所想要的。 或者是,經由分析關鍵詞,取得我們所想要的那一行! 不過,要注意的是,一般來說,擷取訊息通常是針對『一行一行』來分析的, 並不是整篇訊息分析的喔~底下我們介紹兩個很常用的訊息擷取命令:


1) cut

cut 不就是『切』嗎?沒錯啦!這個指令可以將一段訊息的某一段給他『切』出來~ 處理的訊息是以『行』爲單位喔!底下我們就來談一談:

[root@linux ~]# cut -d'分隔字符' -f fields
[root@linux ~]# cut -c 字符區間
參數:
-d :後面接分隔字符。與 -f 一起使用;
-f :依據 -d 的分隔字符將一段訊息分割成爲數段,用 -f 取出第幾段的意思;
-c :以字符 (characters) 的單位取出固定字符區間;


範例一:將 PATH 變量取出,我要找出第三個路徑。
[root@linux ~]# echo $PATH
/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/X11R6/bin:/usr/games:
[root@linux ~]# echo $PATH | cut -d ':' -f 5
# 嘿嘿!如此一來,就會出現 /usr/local/bin 這個目錄名稱!
# 因爲我們是以 : 作爲分隔符,第五個就是 /usr/local/bin 啊!
# 那麼如果想要列出第 3 與第 5 呢?,就是這樣:
[root@linux ~]# echo $PATH | cut -d ':' -f 3,5


範例二:將 export 輸出的訊息,取得第 12 字符以後的所有字符串
[root@linux ~]# export
declare -x HISTSIZE="1000"
declare -x INPUTRC="/etc/inputrc"
declare -x KDEDIR="/usr"
declare -x LANG="zh_TW.big5"
......其它省略......
[root@linux ~]# export | cut -c 12-
HISTSIZE="1000"
INPUTRC="/etc/inputrc"
KDEDIR="/usr"
LANG="zh_TW.big5"
......其它省略......
# 知道怎麼回事了吧?用 -c 可以處理比較具有格式的輸出數據!
# 我們還可以指定某個範圍的值,例如第 12-20 的字符,就是 cut -c 12-20 等等!


範例三:用 last 將這個月登入者的信息中,僅留下使用者大名
[root@linux ~]# last
vbird tty1 192.168.1.28 Mon Aug 15 11:55 - 17:48 (05:53)
vbird tty1 192.168.1.28 Mon Aug 15 10:17 - 11:54 (01:37)
[root@linux ~]# last | cut -d ' ' -f 1
# 用 last 可以取得最近一個月登入主機的使用者信息,
# 而我們可以利用空格符的間隔,取出第一個信息,就是使用者賬號囉!
# 但是因爲 vbird tty1 之間空格有好幾個,並非僅有一個,所以,如果要找出
# tty1 其實不能以 cut -d ' ' -f 1,2 喔!輸出的結果會不是我們想要的。


這個 cut 實在很好用!不過,說真的,除非你常常在分析 log 檔案,否則使用到 cut 的機會並不多!好了! cut 主要的用途在於將『同一行裏面的數據進行分解!』, 最常使用在分析一些數據或文字數據的時候!這是因爲有時候我們會以某些字符當作分割的參數, 然後來將數據加以切割,以取得我們所需要的數據。我也很常使用這個功能呢!尤其是在分析 log 檔案的時候!不過, cut 在處理多空格相連的數據時,可能會比較吃力一點~







2) grep


剛剛的 cut 是將一行訊息當中,取出某部分我們想要的,而 grep 則是分析一行訊息, 若當中有我們所需要的信息,就將該行拿出來~簡單的語法是這樣的:

[root@linux ~]# grep [-acinv] '搜尋字符串' filename
參數:
-a :將 binary 檔案以 text 檔案的方式搜尋數據
-c :計算找到 '搜尋字符串' 的次數
-i :忽略大小寫的不同,所以大小寫視爲相同
-n :順便輸出行號
-v :反向選擇,亦即顯示出沒有 '搜尋字符串' 內容的那一行!



範例一:將 last 當中,有出現 root 的那一行就取出來;
[root@linux ~]# last | grep 'root'


範例二:與範例一相反,只要沒有 root 的就取出!
[root@linux ~]# last | grep -v 'root'


範例三:在 last 的輸出訊息中,只要有 root 就取出,並且僅取第一欄
[root@linux ~]# last | grep 'root' |cut -d ' ' -f1
# 在取出 root 之後,利用上個指令 cut 的處理,就能夠僅取得第一欄囉!


grep 是個很棒的指令喔!他支持的語法實在是太多了~用在正規表示法裏頭, 能夠處理的數據實在是多的很~不過,我們這裏先不談正規表示法~下一章再來說明~ 您先了解一下, grep 可以解析一行文字,取得關鍵詞,若該行有存在關鍵詞, 就會整行列出來!






3) 排序命令: sort, wc, uniq


很多時候,我們都會去計算一次數據裏頭的相同型態的數據總數,舉例來說, 使用 last 可以查得這個月份有登入主機者的身份。那麼我可以針對每個使用者查出他們的總登入次數嗎? 此時就得要排序與計算之類的指令來輔助了!底下我們介紹幾個好用的排序與統計指令喔!


sort

sort 是很有趣的指令,他可以幫我們進行排序,而且可以依據不同的數據型態來排序喔! 例如數字與文字的排序就不一樣。此外,排序的字符與語系的編碼有關,因此, 如果您需要排序時,建議使用 LC_ALL=C 來讓語系統一,數據排序比較好一些。

[root@linux ~]# sort [-fbMnrtuk] [file or stdin]
參數:
-f :忽略大小寫的差異,例如 A 與 a 視爲編碼相同;
-b :忽略最前面的空格符部分;
-M :以月份的名字來排序,例如 JAN, DEC 等等的排序方法;
-n :使用『純數字』進行排序(預設是以文字型態來排序的);
-r :反向排序;
-u :就是 uniq ,相同的數據中,僅出現一行代表;
-t :分隔符,預設是 tab 鍵;
-k :以那個區間 (field) 來進行排序的意思,


範例一:個人賬號都記錄在 /etc/passwd 下,請將賬號進行排序。

[root@linux ~]# cat /etc/passwd | sort
adm:x:3:4:adm:/var/adm:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

# 我省略很多的輸出~由上面的數據看起來, sort 是預設『以第一個』數據來排序
# 而且預設是以『文字』型態來排序的喔!所以由 a 開始排到最後囉!



範例二:/etc/passwd 內容是以 : 來分隔的,我想以第三欄來排序,該如何?

[root@linux ~]# cat /etc/passwd | sort -t ':' -k 3
root:x:0:0:root:/root:/bin/bash
iiimd:x:100:101:IIIMF server:/usr/lib/iiim:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
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

# 看到特殊字體的輸出部分了吧?怎麼會這樣排列啊?呵呵!沒錯啦~
# 如果是以文字型態來排序的話,原本就會是這樣,想要使用數字排序:
# cat /etc/passwd | sort -t ':' -k 3 -n
# 這樣才行啊!用那個 -n 來告知 sort 以數字來排序啊!



範例三:利用 last ,將輸出的數據僅取賬號,並加以排序

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


sort 同樣是很常用的指令呢!因爲我們常常需要比較一些信息啦! 舉個上面的第二個例子來說好了!今天假設你有很多的賬號,而且你想要知道最大的使用者 ID 目前到哪一號了!呵呵!使用 sort 一下子就可以知道答案咯!當然其使用還不止此啦! 有空的話不妨玩一玩!



uniq

如果我排序完成了,想要將重複的資料僅列出一個顯示,可以怎麼做呢?

[root@linux ~]# uniq [-ic]
參數:
-i :忽略大小寫字符的不同;
-c :進行計數


範例一:使用 last 將賬號列出,僅取出賬號欄,進行排序後僅取出一位;
[root@linux ~]# last | cut -d ' ' -f1 | sort | uniq

範例二:承上題,如果我還想要知道每個人的登入總次數呢?
[root@linux ~]# last | cut -d ' ' -f1 | sort | uniq -c


這個指令用來將『重複的行刪除掉只顯示一個』,舉個例子來說, 你要知道這個月份登入你主機的使用者有誰,而不在乎他的登入次數,那麼就使用上面的範例, (1)先將所有的數據列出;(2)再將人名獨立出來;(3)經過排序;(4)只顯示一個! 由於這個指令是在將重複的東西減少,所以當然需要『配合排序過的檔案』來處理囉!



wc

如果我想要知道 /etc/man.config 這個檔案裏面有多少字?多少行?多少字符的話, 可以怎麼做呢?其實可以利用 wc 這個指令來達成喔!他可以幫我們計算輸出的訊息的整體數據!

[root@linux ~]# wc [-lwm]
參數:
-l :僅列出行;
-w :僅列出多少字(英文單字);
-m :多少字符;


範例一:那個 /etc/man.config 裏面到底有多少相關字、行、字符數?
[root@linux ~]# cat /etc/man.config | wc
138 709 4506
# 輸出的三個數字中,分別代表: 『行、字數、字符數』


範例二:我知道使用 last 可以輸出登入者,但是 last 最後兩行並非賬號內容,那麼請問,我該如何以一行指令串取得這個月份登入系統的總人次?

[root@linux ~]# last | grep [a-zA-Z] | grep -v 'wtmp' | wc -l

# 由於 last 會輸出空白行與 wtmp 字樣在最底下兩行,因此,我利用
# grep 取出非空白行,以及去除 wtmp 那一行,在計算行數,就能夠了解囉!


wc 也可以當作指令?呵呵!這可不是上洗手間的 WC 呢! 這是相當有用的計算檔案內容的一個工具組喔!舉個例子來說, 當你要知道目前你的賬號檔案中有多少個賬號時,就使用這個方法:『 cat /etc/passwd | wc -l 』啦!因爲 /etc/passwd 裏頭一行代表一個使用者呀! 所以知道行數就曉得有多少的賬號在裏頭了!而如果要計算一個檔案裏頭有多少個字符時,呵呵!就使用 wc -c 這個參數吧!






雙向重導向: tee


想個簡單的東西,我們由前一節知道 > 會將數據流整個傳送給檔案或裝置, 因此我們除非去讀取該檔案或裝置,否則就無法繼續利用這個數據流。 萬一我想要將這個數據流的處理過程中,將某段訊息存下來,應該怎麼做?呵呵! 利用 tee 就可以囉 

同時將數據流分送到檔案去與屏幕 (screen);而輸出到屏幕的,其實就是 stdout ,可以讓下個指令繼續處理喔!


[root@linux ~]# tee [-a] file
參數:
-a :以累加 (append) 的方式,將數據加入 file 當中!


[root@linux ~]# last | tee last.list | cut -d " " -f1
# 這個範例可以讓我們將 last 的輸出存一份到 last.list 檔案中;


[root@linux ~]# ls -l /home | tee ~/homefile | more
# 這個範例則是將 ls 的數據存一份到 ~/homefile ,同時屏幕也有輸出訊息!


[root@linux ~]# ls -l / | tee -a ~/homefile | more
# 要注意: tee 後接的檔案會被覆蓋,所以,我們要加上 -a
# 這個參數才能將訊息累加。


有沒有發現在命令重導向的時候,如果我們要將數據送出到檔案的時候, 屏幕上就不會出現任何的數據!那麼如果我們需要將數據同時顯示在屏幕上跟檔案中呢?呵呵!這個時候就需要 tee 這個指令囉!使用 last 可以查看到這個月份的登入資料,而使用了 tee 之後,會將數據同時傳給下一個命令去執行,也會將數據寫入 last.list 這個檔案中!也是個好幫手!







字符轉換命令: tr, col, join, paste, expand


我們在 vi 文書處理器 章節當中,提到過 DOS 斷行字符與 Unix 斷行字符的不同, 並且可以使用 dos2unix 與 unix2dos 來完成轉換。好了,那麼思考一下,是否還有其它常用的字符替代? 舉例來說,要將大寫改成小寫,或者是 [tab] 按鍵轉成空格鍵?還有,如何將兩篇訊息整合成一篇? 底下我們就來介紹一下這些字符轉換命令在管線當中的使用方法:

tr

tr 可以用來刪除一段訊息當中的文字,或者是進行文字訊息的替換!

[root@linux ~]# tr [-ds] SET1 ...
參數:
-d :刪除訊息當中的 SET1 這個字符串;
-s :取代掉重複的字符!


範例一:將 last 輸出的訊息中,所有的小寫變成大寫字符:
[root@linux ~]# last | tr '[a-z]' '[A-Z]'

範例二:將 /etc/passwd 輸出的訊息中,將冒號 (:) 刪除
[root@linux ~]# cat /etc/passwd | tr -d ':'

範例三:將 DOS 檔案的斷行字符 ^M 符號刪除:
[root@linux ~]# cat /home/test/dostxt | tr -d '\r' > dostxt-noM

# 那個 /r 指的是 DOS 的斷行字符,關於更多的字符,請參考 man tr其實這個指令也可以寫在『正規表示法』裏頭!因爲他也是由正規表示法的方式來取代數據的! 以上面的例子來說,使用 [] 可以設定一串字呢! 也常常用來取代檔案中的怪異符號! 例如上面第三個例子當中,可以去除 DOS 檔案留下來的 ^M 這個斷行的符號!這東西相當的有用!相信處理 Linux & Windows 系統中的人們最麻煩的一件事就是這個事情啦!亦即是 DOS 底下會自動的在每行行尾加入 ^M 這個斷行符號!這個時候我們可以使用這個 tr 來將 ^M 去除! ^M 可以使用 \r 來代替之!



col
[root@linux ~]# col [-x]
參數:
-x :將 tab 鍵轉換成對等的空格鍵

範例:
[root@linux ~]# cat -A /etc/man.config <==此時會看到很多 ^I 的符號,那就是 tab
[root@linux ~]# cat /etc/man.config | col -x | cat -A | more
# 嘿嘿!如此一來, [tab] 按鍵會被取代成爲空格鍵,輸出就美觀多了!雖然 col 有他特殊的用途,不過,很多時候,他可以用來簡單的處理將 [tab] 按鍵取代成爲空格鍵! 例如上面的例子當中,如果使用 cat -A 則 [tab] 會以 ^I 來表示。 但經過 col -x 的處理,則會將 [tab] 取代成爲對等的空格鍵!



join

join 看字面上的意義 (加入/參加) 就可以知道,他是在處理兩個檔案之間的數據, 而且,主要是在處理『兩個檔案當中,有 "相同數據" 的那一行,將他加在一起』的意思。我們利用底下的簡單例子來說明:

[root@linux ~]# join [-ti12] file1 file2
參數:
-t :join 預設以空格符分隔數據,並且比對『第一個字段』的數據,
如果兩個檔案相同,則將兩筆數據聯成一行,且第一個字段放在第一個!
-i :忽略大小寫的差異;
-1 :這個是數字的 1 ,代表『第一個檔案要用那個字段來分析』的意思;
-2 :代表『第二個檔案要用那個字段來分析』的意思。



範例一:用 root 的身份,將 /etc/passwd 與 /etc/shadow 相關數據整合成一欄

[root@linux ~]# join -t ':' /etc/passwd /etc/shadow
bin:x:1:1:bin:/bin:/sbin/nologin:*:12959:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin:*:12959:0:99999:7:::
adm:x:3:4:adm:/var/adm:/sbin/nologin:*:12959:0:99999:7:::
# 因爲 /etc/shadow 的權限問題,所以這裏必須是 root 才能動作!而 /etc/passwd
# 與 /etc/shadow 都是以 : 來分隔字段,所以必須要使用 -t ':' 規範字段分隔字符。
# 且,因爲 /etc/shadow 與 /etc/passwd 剛好都是以第一個字段爲賬號名稱,所以,
# 就可以將同一行的數據給他貼在一起了!
# 另外,再仔細看一下 /etc/shadow 的內容與 /etc/passwd 的內容,您會發現,
# 兩者都以賬號爲開始,而上面的輸出數據中您會發現特殊字體部分,那代表
# 第二個檔案的內容。在第二個檔案的內容部分,由於賬號(第一個字段)與
# 第一的檔案是相同的,所以當然就省略掉,因此就成爲上面的輸出。



範例二:我們知道 /etc/passwd 第四個字段是 GID ,那個 GID 記錄在/etc/group 當中的第三個字段,請問如何將兩個檔案整合?

[root@linux ~]# 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:root,bin,daemon
2:daemon:x:2:daemon:/sbin:/sbin/nologin:daemon:x:root,bin,daemon
4:adm:x:3:adm:/var/adm:/sbin/nologin:adm:x:root,adm,daemon
# 這個例子就更明顯了!原本的 /etc/passwd 的第一行內容應該是:
# root:x:0:0:root:/root:/bin/bash
# 至於 /etc/group 第一行內容應該是:
# root:x:0:
# 我將第一個檔案的第四欄與第二個檔案的第三欄取出,放置到輸出的最前方,
# 然後將剩下的數據給他加在一起!就成了上面的輸出啦!


這個 join 在處理兩個相關的數據文件時,就真的是很有幫助的啦! 例如上面的案例當中,我的 /etc/passwd, /etc/shadow, /etc/group 都是有相關性的, 其中 /etc/passwd, /etc/shadow 以賬號爲相關性,至於 /etc/passwd, /etc/group 則以所謂的 GID (賬號的數字定義) 來作爲他的相關性。根據這個相關性, 我們可以將有關係的資料放置在一起!這在處理數據可是相當有幫助的! 但是上面的例子有點難,希望您可以靜下心好好的看一看原因喔!



paste

這個 paste 就要比 join 簡單多了!相對於 join 必須要比對兩個檔案的數據相關性, paste 就直接『將兩行貼在一起,且中間以 [tab] 鍵隔開』而已

簡單的使用方法:

[root@linux ~]# paste [-d] file1 file2
參數:
-d :後面可以接分隔字符。預設是以 [tab] 來分隔的!
- :如果 file 部分寫成 - ,表示來自 standard input 的資料的意思。


範例一:將 /etc/passwd 與 /etc/shadow 同一行貼在一起

[root@linux ~]# paste /etc/passwd /etc/shadow
bin:x:1:1:bin:/bin:/sbin/nologin bin:*:12959:0:99999:7:::
daemon:x:2:2:daemon:/sbin:/sbin/nologin daemon:*:12959:0:99999:7:::
adm:x:3:4:adm:/var/adm:/sbin/nologin adm:*:12959:0:99999:7:::
# 注意喔!同一行中間是以 [tab] 按鍵隔開的!


範例二:先將 /etc/group 讀出(用 cat),然後與範例一貼上一起!且僅取出前三行

[root@linux ~]# cat /etc/group|paste /etc/passwd /etc/shadow -|head -n 3
# 這個例子的重點在那個 - 的使用!那玩意兒常常代表 stdin 喔!


expand

這玩意兒就是在將 [tab] 按鍵轉成空格鍵啦~可以這樣玩:

[root@linux ~]# expand [-t] file
參數:
-t :後面可以接數字。一般來說,一個 tab 按鍵可以用 8 個空格鍵取代。
我們也可以自行定義一個 [tab] 按鍵代表多少個字符呢!


範例一:將 /etc/man.config 內行首爲 MANPATH 的字樣就取出;僅取前三行;
[root@linux ~]# grep '^MANPATH' /etc/man.config | head -n 3
MANPATH /usr/man
MANPATH /usr/share/man
MANPATH /usr/local/man
# 行首的代表標誌爲 ^ ,這個我們留待下節介紹!先有概念即可!


範例二:承上,如果我想要將所有的符號都列出來?(用 cat)
[root@linux ~]# grep '^MANPATH' /etc/man.config | head -n 3 |cat -A
MANPATH^I/usr/man$
MANPATH^I/usr/share/man$
MANPATH^I/usr/local/man$
# 發現差別了嗎?沒錯~ [tab] 按鍵可以被 cat -A 顯示成爲 ^I


範例三:承上,我將 [tab] 按鍵設定成 6 個字符的話?
[root@linux ~]# grep '^MANPATH' /etc/man.config | head -n 3 | \
> expand -t 6 - | cat -A
MANPATH /usr/man$
MANPATH /usr/share/man$
MANPATH /usr/local/man$
123456123456123456.....
# 仔細看一下上面的數字說明,因爲我是以 6 個字符來代表一個 [tab] 的長度,所以,
# MAN... 到 /usr 之間會隔 12 (兩個 [tab]) 個字符喔!如果 tab 改成 9 的話,
# 情況就又不同了!這裏也不好理解~您可以多設定幾個數字來查閱就曉得!expand 也是挺好玩的~他會自動將 [tab] 轉成空格鍵~所以,以上面的例子來說, 使用 cat -A 就會查不到 ^I 的字符囉~此外,因爲 [tab] 最大的功能就是格式排列整齊! 我們轉成空格鍵後,這個空格鍵也會依據我們自己的定義來增加大小~ 所以,並不是一個 ^I 就會換成 8 個空白喔!這個地方要特別注意的哩! 此外,您也可以參考一下 unexpand 這個將空白轉成 [tab] 的指令功能啊! ^_^



分割命令: split

如果你有檔案太大,導致一些攜帶式裝置無法複製的問題,嘿嘿!找 split 就對了! 他可以幫你將一個大檔案,依據檔案大小或行數來分割,就可以將大檔案分割成爲小檔案了! 快速又有效啊!真不錯~

[root@linux ~]# split [-bl] file PREFIX
參數:
-b :後面可接欲分割成的檔案大小,可加單位,例如 b, k, m 等;
-l :以行數來進行分割。


範例一:我的 /etc/termcap 有七百多K,若想要分成 300K 一個檔案時?
[root@linux ~]# cd /tmp; split -b 300k /etc/termcap termcap
[root@linux tmp]# ls -l termcap*
-rw-rw-r-- 1 root root 307200 8月 17 00:25 termcapaa
-rw-rw-r-- 1 root root 307200 8月 17 00:25 termcapab
-rw-rw-r-- 1 root root 184848 8月 17 00:25 termcapac
# 那個檔名可以隨意取的啦!我們只要寫上前導文字,小檔案就會以
# xxxaa, xxxab, xxxac 等方式來建立小檔案的!


範例二:如何將上面的三個小檔案合成一個檔案,檔名爲 termcapback
[root@linux tmp]# cat termcap* >> termcapback
# 很簡單吧?就用數據流重導向就好啦!簡單!


範例三:使用 ls -al / 輸出的信息中,每十行記錄成一個檔案
[root@linux tmp]# ls -al / | split -l 10 - lsroot
# 重點在那個 - 啦!一般來說,如果需要 stdout/stdin 時,但偏偏又沒有檔案,
# 有的只是 - 時,那麼那個 - 就會被當成 stdin 或 stdout ~


在 Windows 的情況下,你要將檔案分割需要如何作?!傷腦筋吧!呵呵!在 Linux 底下就簡單的多了!你要將檔案分割的話,那麼就使用 -b size 來將一個分割的檔案限制其大小,如果是行數的話,那麼就使用 -l line 來分割!好用的很!如此一來,你就可以輕易的將你的檔案分割成 floppy 的大小,方便你 copy 囉!




參數代換: xargs


 xargs 可以讀入 stdin 的數據,並且以空格符或斷行字符作爲分辨,將 stdin 的資料分隔成爲 arguments 。 因爲是以空格符作爲分隔,所以,如果有一些檔名或者是其它意義的名詞內含有空格符的時候, xargs 可能就會誤判了~他的用法其實也還滿簡單的!就來看一看先!


[root@linux ~]# xargs [-0epn] command
參數:
-0 :如果輸入的 stdin 含有特殊字符,例如 `, \, 空格鍵等等字符時,這個 
-0 參數可以將他還原成一般字符。這個參數可以用於特殊狀態喔!
-e :這個是 EOF (end of file) 的意思。後面可以接一個字符串,當 xargs 分析到這個字符串時,就會停止繼續工作!
-p :在執行每個指令的 argument 時,都會詢問使用者的意思;
-n :後面接次數,每次 command 指令執行時,要使用幾個參數的意思。看範例三。

當 xargs 後面沒有接任何的指令時,預設是以 echo 來進行輸出喔!



範例一:將 /etc/passwd 內的第一欄取出,僅取三行,使用 finger 這個指令將每個賬號內容秀出來

[root@linux ~]# 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 後面需要的參數!


範例二:同上,但是每次執行 finger 時,都要詢問使用者是否動作?
[root@linux ~]# cut -d':' -f1 < /etc/passwd |head -n 3| xargs -p finger
finger root bin daemon ?...y
......底下省略.....
# 呵呵!這個 -p 的參數有趣了吧?!他可以讓使用者的使用過程中,被詢問到每個
# 指令是否執行!


範例三:將所有的 /etc/passwd 內的賬號都以 finger 查閱,但一次僅查閱五個賬號
[root@linux ~]# cut -d':' -f1 < /etc/passwd | xargs -p -n 5 finger
finger root bin daemon adm lp ?...y
......底下省略.....
# 在這裏鳥哥使用了 -p 這個參數來讓您對於 -n 更有概念。一般來說,某些指令後面
# 可以接的 arguments 是有限制的,不能無限制的累加,此時,我們可以利用 -n
# 來幫助我們將參數分成數個部分,每個部分分別再以指令來執行!這樣就 OK 啦!^_^
[root@linux ~]#


範例四:同上,但是當分析到 lp 就結束這串指令?
[root@linux ~]# cut -d':' -f1 < /etc/passwd | xargs -p -e'lp' finger
finger root bin daemon adm ?...
# 仔細與上面的案例做比較。也同時注意,那個 -e'lp' 是連在一起的,中間沒有空格鍵。
# 上個例子當中,第五個參數是 lp 啊,那麼我們下達 -e'lp' 後,則分析到 lp
# 這個字符串時,後面的其它 stdin 的內容就會被 xargs 捨棄掉了!

其實,在 man xargs 裏面就有三四個小范例,您可以自行參考一下內容。 此外, xargs 真的是很好用的一個玩意兒!您真的需要好好的參詳參詳!



關於減號 - 的用途


管線命令在 bash 的連續的處理程序中是相當重要的!另外,在 log file 的分析當中也是相當重要的一環, 所以請特別留意!另外,在管線命令當中,常常會使用到前一個指令的 stdout 作爲這次的 stdin , 某些指令需要用到文件名稱 (例如 tar) 來進行處理時,該 stdin 與 stdout 可以利用減號 "-" 來替代, 舉例來說:

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

上面這個例子是說:『我將 /home 裏面的檔案給他打包,但打包的數據不是紀錄到檔案,而是傳送到 stdout; 經過管線後,將 tar -cvf - /home 傳送給後面的 tar -xvf - 』。後面的這個 - 則是取用前一個指令的 stdout, 因此,我們就不需要使用 file 了!這是很常見的例子喔!注意注意!





Bash shell(1-6)  例題


在 Linux 上可以找到哪些 shell(舉出三個) ?那個檔案記錄可用的 shell ?而 Linux 預設的 shell 是?
1) /bin/bash, /bin/tcsh, /bin/csh 2) /etc/shells 3) bash ,亦即是 /bin/bash。


在 shell 環境下,有個提示字符 (prompt),他可以修改嗎?要改什麼?預設的提示字符內容是?
可以修改的,改 PS1 這個變量,這個 PS1 變量的預設內容爲:『[\u@\h \W]\$』


如何顯示 HOME 這個環境變量?
echo $HOME


如何得知目前的所有變量與環境變量的設定值?
環境變量用 env 而所有變量用 set 即可顯示


我是否可以設定一個變量名稱爲 3myhome ?
不行!變量不能以數字做爲開頭,參考變量設定規則的內容


在這樣的練習中『A=B』且『B=C』,若我下達『unset $A』,則取消的變數是 A 還是 B?
被取消的是 B 喔,因爲 unset $A 相當於 unset B 所以取消的是 B ,A 會繼續存在!


如何取消變量與命令別名的內容?
使用 unset 及 unalias 即可


如何設定一個變量名稱爲 name 內容爲 It's my name ?
name=It\'s\ my\ name 或 name="It's my name"


環境變量檔案的加載順序?
先由 /etc/passwd 取得 bash 這個 shell ,再到 /etc/profile 讀取主要的環境變量,同時亦會將 /etc/inputrc 及 /etc/profile.d 內容均讀入。之後,再到個人的家目錄讀取 ~/.bash_profile 及 ~/.bashrc 等檔案!


man page 的路徑設定檔案?
/etc/man.config 或 /etc/man.conf


試說明 ', ", 與 ` 這些符號在變量定義中的用途?
參考變量規則那一章節,其中, " 可以具有變量的內容屬性, ' 則僅有一般字符,至於 ` 之內則是可先被執行的指令。


跳脫符號 \ 有什麼用途?
可以用來跳脫特殊字符,例如 Enter, $ 等等,使成爲一般字符!


連續命令中, ;, &&, || 有何不同?
分號可以讓兩個 command 連續運作,不考慮 command1 的輸出狀態, && 則前一個指令必需要沒有錯誤訊息,亦即回傳值需爲 0 則 command2 纔會被執行, || 則與 && 相反!


如何將 last 的結果中,獨立出賬號,並且印出本月份曾經登入過的賬號?
last | cut –d “ “ –f1 | sort | uniq


請問 foo1 && foo2 | foo3 > foo4 ,這個指令串當中, foo1/foo2/foo3/foo4 是指令還是檔案? 整串指令的意義爲?
foo1/foo2 與 foo3 都是指令, foo4 是裝置或檔案。整串指令意義爲:
1. 當 foo1 執行結果有錯誤時,則該指令串結束;
2. 若 foo1 執行結果沒有錯誤時,則執行 foo2 | foo3 > foo4 ;
1. foo2 將 stdout 輸出的結果傳給 foo3 處理;
2. foo3 將來自 foo2 的 stdout 當成 stdin ,處理完後將數據流重新導向 foo4 這個裝置/檔案


如何秀出在 /bin 底下任何以 a 爲開頭的檔案文件名的詳細資料?
ls -l /bin/a*


如何秀出 /bin 底下,文件名爲四個字符的檔案?
ls -l /bin/????


如何秀出 /bin 底下,檔名開頭不是 a-d 的檔案?
ls -l /bin/[!a-d]*


當我離開 bash 後,希望系統可以幫我將最近工作的:1)工作日期; 2)100 個歷史命令獨立 記錄到 ~/.bash_localcom 檔案中,該如何設定?
我可以編輯 ~/.bash_logout ,將這個檔案內容變成: # ~/.bash_logout date >> ~/.bash_localcom history 100 >> ~/.bash_localcom clear


我想要讓終端機接口的登入提示字符修改成我自己喜好的模樣,應該要改哪裏?(filename)
/etc/issue


承上題,如果我是想要讓使用者登入後,才顯示歡迎訊息,又應該要改哪裏?
/etc/motd

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章