Linux 管道
管道命令
“ | ”,豎線符號代表的就是管道符
管道是一種兩個進程間進行單向通信的機制。因為管道傳遞數據的單向性,所以又稱為半雙工管道。
介紹:
- 管道可以根據一組命令按照數據流向的方式來進行操作。簡單的說,第一個命令執行後,不回顯結果,而是把結果通過管道傳遞給第二個命令,第二個命令處理後再傳給第三個….直到沒有管道符後才終止命令,並回顯最終結果。
- 管道可以把不同的命令組合成強大的指令集合。比如,對文件夾下所有的txt結尾的文件重命名,就需要三個管道符號,四個命令完成。
缺點:
- 數據只能從一個進程流向另一個進程(其中一個讀管道,一個寫管道)。如果要進行雙工通信,需要建立兩個管道。
- 管道只能用於父子進程或兄弟進程間通信,也就是說管道只能用於具有親緣關系的進程間通信。
- 管道所傳輸的是無格式的字節流。
通過管道通信的兩個進程,一個進程向管道寫數據,另一個從中讀數據。寫入的數據每次都添加到管道緩沖區的末尾,讀數據的時候都是沖緩沖區的頭部讀出數據的。
利用管道查看/root/install.log文件的內容並分頁顯示
[root@ylg ~]# cat install.log | more
對於常用的可以直接用於管道的命令,主要有:
cut 用來顯示行中的指定部分,刪除文件中指定字段。
grep grep(global search regular expression(RE) and print out the line,全面搜索正則表達式並把行打印出來)是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行打印出來。
sort 用於將文本文件內容加以排序。sort可針對文本文件的內容,以行為單位來排序。
uniq 用於報告或忽略文件中的重復行,一般與sort命令結合使用。
wc 用來計算數字。利用wc指令我們可以計算文件的Byte數、字數或是列數,若不指定文件名稱,或是所給予的文件名為“-”,則wc指令會從標準輸入設備讀取數據。
tee 用於讀取標準輸入的數據,並將其內容輸出成文件。tee指令會從標準輸入設備讀取數據,將其內容輸出到標準輸出設備,同時保存成文件。
tee [-ai][--help][--version][文件...] -a或--append 附加到既有文件的後面,而非覆蓋它. -i或--ignore-interrupts 忽略中斷信號。
tr 可以對來自標準輸入的字符進行替換、壓縮和刪除。它可以將一組字符變成另一組字符,經常用來編寫優美的單行命令,作用很強大。
col 用於過濾控制字符。在許多UNIX說明文件裏,都有RLF控制字符。當我們運用shell特殊字符">"和">>",把說明文件的內容輸出成純文本文件時,控制字符會變成亂碼,col指令則能有效濾除這些控制字符。
join 用於將兩個文件中,指定欄位內容相同的行連接起來。找出兩個文件中,指定欄位內容相同的行,並加以合並,再輸出到標準輸出設備。
paste paste命令用於合並文件的列。paste指令會把每個文件以列對列的方式,一列列地加以合並。和join命令類似。
paste [-s][-d <間隔字符>][--help][--version][文件...] -d<間隔字符>或--delimiters=<間隔字符> 用指定的間隔字符取代跳格字符。 -s或--serial 串列進行而非平行處理。
expand 用於將文件的制表符(TAB)轉換為空白字符(space),將結果顯示到標準輸出設備。
xargs
cut
語法
cut [-bn] [file]
cut [-c] [file]
cut [-df] [file]
使用說明:
cut 命令從文件的每一行剪切字節、字符和字段並將這些字節、字符和字段寫至標準輸出。
如果不指定 File 參數,cut 命令將讀取標準輸入。必須指定 -b、-c 或 -f 標誌之一。
參數
對象 | 說明 |
---|---|
-b | 僅顯示行中指定直接範圍的內容; |
-c | 僅顯示行中指定範圍的字符; |
-d | 指定字段的分隔符,默認的字段分隔符為“TAB”; |
-f | 顯示指定字段的內容; |
-n | 與“-b”選項連用,不分割多字節字符; |
--complement | 補足被選擇的字節、字符或字段; |
--out-delimiter=<字段分隔符> | 指定輸出內容是的字段分割符; |
--help | 顯示指令的幫助信息; |
--version | 顯示指令的版本信息。 |
指定字段的字符或者字節範圍
cut命令可以將一串字符作為列來顯示,字符字段的記法:
- N-:從第N個字節、字符、字段到結尾;
- N-M:從第N個字節、字符、字段到第M個(包括M在內)字節、字符、字段;
- -M:從第1個字節、字符、字段到第M個(包括M在內)字節、字符、字段。
上面是記法,結合下面選項將摸個範圍的字節、字符指定為字段:
- -b 表示字節;
- -c 表示字符;
- -f 表示定義字段。
實例
[root@localhost text]# cat test.txt
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz
打印第1個到第3個字符:
[root@localhost text]# cut -c1-3 test.txt
abc
abc
abc
abc
abc
打印前2個字符:
[root@localhost text]# cut -c-2 test.txt
ab
ab
ab
ab
ab
打印從第5個字符開始到結尾:
[root@localhost text]# cut -c5- test.txt
efghijklmnopqrstuvwxyz
efghijklmnopqrstuvwxyz
efghijklmnopqrstuvwxyz
efghijklmnopqrstuvwxyz
efghijklmnopqrstuvwxyz
grep
grep(global search regular expression(RE) and print out the line,全面搜索正則表達式並把行打印出來)是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行打印出來。
語法
grep [-abcEFGhHilLnqrsvVwxy][-A<顯示列數>][-B<顯示列數>][-C<顯示列數>][-d<進行動作>][-e<範本樣式>][-f<範本文件>][--help][範本樣式][文件或目錄...]
選項
對象 | 說明 |
---|---|
-a或--text | 不要忽略二進制的數據。 |
-A<顯示列數>或--after-context=<顯示列數> | 除了顯示符合範本樣式的那一列之外,並顯示該列之後的內容。 |
-b或--byte-offset | 在顯示符合範本樣式的那一列之前,標示出該列第一個字符的位編號。 |
-B<顯示列數>或--before-context=<顯示列數> | 除了顯示符合範本樣式的那一列之外,並顯示該列之前的內容。 |
-c或--count | 計算符合範本樣式的列數。 |
-C<顯示列數>或--context=<顯示列數>或-<顯示列數> | 除了顯示符合範本樣式的那一列之外,並顯示該列之前後的內容。 |
-d<進行動作>或--directories=<進行動作> | 當指定要查找的是目錄而非文件時,必須使用這項參數,否則grep指令將回報信息並停止動作。 |
-e<範本樣式>或--regexp=<範本樣式> | 指定字符串做為查找文件內容的範本樣式。 |
-E或--extended-regexp | 將範本樣式為延伸的普通表示法來使用。 |
-f<範本文件>或--file=<範本文件> | 指定範本文件,其內容含有一個或多個範本樣式,讓grep查找符合範本條件的文件內容,格式為每列一個範本樣式。 |
-F或--fixed-regexp | 將範本樣式視為固定字符串的列表。 |
-G或--basic-regexp | 將範本樣式視為普通的表示法來使用。 |
-h或--no-filename | 在顯示符合範本樣式的那一列之前,不標示該列所屬的文件名稱。 |
-H或--with-filename | 在顯示符合範本樣式的那一列之前,表示該列所屬的文件名稱。 |
-i或--ignore-case | 忽略字符大小寫的差別。 |
-l或--file-with-matches | 列出文件內容符合指定的範本樣式的文件名稱。 |
-L或--files-without-match | 列出文件內容不符合指定的範本樣式的文件名稱。 |
-n或--line-number | 在顯示符合範本樣式的那一列之前,標示出該列的列數編號。 |
-q或--quiet或--silent | 不顯示任何信息。 |
-r或--recursive | 此參數的效果和指定"-d |
-s或--no-messages | 不顯示錯誤信息。 |
-v或--revert-match | 反轉查找。 |
-V或--version | 顯示版本信息。 |
-w或--word-regexp | 只顯示全字符合的列。 |
-x或--line-regexp | 只顯示全列符合的列。 |
-y | 此參數的效果和指定"-i"參數相同。 |
--help | 在線幫助。 |
實例
實例
1、在當前目錄中,查找後綴有 file 字樣的文件中包含 test 字符串的文件,並打印出該字符串的行。此時,可以使用如下命令:
grep test *file
結果如下所示:
$ grep test test* #查找後綴有“test”的文件包含“test”字符串的文件
testfile1:This a Linux testfile! #列出testfile1 文件中包含test字符的行
testfile_2:This is a linux testfile! #列出testfile_2 文件中包含test字符的行
testfile_2:Linux test #列出testfile_2 文件中包含test字符的行
2、以遞歸的方式查找符合條件的文件。例如,查找指定目錄/etc/acpi 及其子目錄(如果存在子目錄的話)下所有文件中包含字符串"update"的文件,並打印出該字符串所在行的內容,使用的命令為:
grep -r update /etc/acpi
輸出結果如下:
$ grep -r update /etc/acpi #以遞歸的方式查找“etc/acpi”
#下包含“update”的文件
/etc/acpi/ac.d/85-anacron.sh:# (Things like the slocate updatedb cause a lot of IO.)
Rather than
/etc/acpi/resume.d/85-anacron.sh:# (Things like the slocate updatedb cause a lot of
IO.) Rather than
/etc/acpi/events/thinkpad-cmos:action=/usr/sbin/thinkpad-keys--update
3、反向查找。前面各個例子是查找並打印出符合條件的行,通過"-v"參數可以打印出不符合條件行的內容。
查找文件名中包含 test 的文件中不包含test 的行,此時,使用的命令為:
grep -v test *test*
結果如下所示:
$ grep-v test* #查找文件名中包含test 的文件中不包含test 的行
testfile1:helLinux!
testfile1:Linis a free Unix-type operating system.
testfile1:Lin
testfile_1:HELLO LINUX!
testfile_1:LINUX IS A FREE UNIX-TYPE OPTERATING SYSTEM.
testfile_1:THIS IS A LINUX TESTFILE!
testfile_2:HELLO LINUX!
testfile_2:Linux is a free unix-type opterating system.
4、打印出匹配文本之前或者之後的行
#顯示匹配某個結果之後的3行,使用 -A 選項:
seq 10 | grep "5" -A 3
5
6
7
8
#顯示匹配某個結果之前的3行,使用 -B 選項:
seq 10 | grep "5" -B 3
2
3
4
5
#顯示匹配某個結果的前三行和後三行,使用 -C 選項:
seq 10 | grep "5" -C 3
2
3
4
5
6
7
8
#如果匹配結果有多個,會用“--”作為各匹配結果之間的分隔符:
echo -e "a\nb\nc\na\nb\nc" | grep a -A 1
a
b
--
a
b
sort
Linux sort命令用於將文本文件內容加以排序。sort可針對文本文件的內容,以行為單位來排序。
語法
sort [-bcdfimMnr][-o<輸出文件>][-t<分隔字符>][+<起始欄位>-<結束欄位>][--help][--verison][文件]
選項
對象 | 說明 |
---|---|
-b | 忽略每行前面開始出的空格字符。 |
-c | 檢查文件是否已經按照順序排序。 |
-d | 排序時,處理英文字母、數字及空格字符外,忽略其他的字符。 |
-f | 排序時,將小寫字母視為大寫字母。 |
-i | 排序時,除了040至176之間的ASCII字符外,忽略其他的字符。 |
-m | 將幾個排序好的文件進行合並。 |
-M | 將前面3個字母依照月份的縮寫進行排序。 |
-n | 依照數值的大小排序。 |
-o<輸出文件> | 將排序後的結果存入指定的文件。 |
-r | 以相反的順序來排序。 |
-t<分隔字符> | 指定排序時所用的欄位分隔字符。 |
+<起始欄位>-<結束欄位> | 以指定的欄位來排序,範圍由起始欄位到結束欄位的前一欄位。 |
--help | 顯示幫助。 |
--version | 顯示版本信息。 |
-k選項的具體語法格式:
-k選項的語法格式:
FStart.CStart Modifie,FEnd.CEnd Modifier
-------Start--------,-------End--------
FStart.CStart 選項 , FEnd.CEnd 選項
這個語法格式可以被其中的逗號,
分為兩大部分,Start部分和End部分。Start部分也由三部分組成,其中的Modifier部分就是我們之前說過的類似n和r的選項部分。我們重點說說Start
部分的FStart
和C.Start
。C.Start
也是可以省略的,省略的話就表示從本域的開頭部分開始。FStart.CStart
,其中FStart
就是表示使用的域,而CStart
則表示在FStart
域中從第幾個字符開始算“排序首字符”。同理,在End部分中,你可以設定FEnd.CEnd
,如果你省略.CEnd
,則表示結尾到“域尾”,即本域的最後一個字符。或者,如果你將CEnd設定為0(零),也是表示結尾到“域尾”。
從公司英文名稱的第二個字母開始進行排序:
$ sort -t ' ' -k 1.2 facebook.txt
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
使用了-k 1.2
,表示對第一個域的第二個字符開始到本域的最後一個字符為止的字符串進行排序。你會發現baidu因為第二個字母是a而名列榜首。sohu和 google第二個字符都是o,但sohu的h在google的o前面,所以兩者分別排在第二和第三。guge只能屈居第四了。
只針對公司英文名稱的第二個字母進行排序,如果相同的按照員工工資進行降序排序:
$ sort -t ' ' -k 1.2,1.2 -nrk 3,3 facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
由於只對第二個字母進行排序,所以我們使用了-k 1.2,1.2
的表示方式,表示我們“只”對第二個字母進行排序。(如果你問“我使用-k 1.2
怎麽不行?”,當然不行,因為你省略了End部分,這就意味著你將對從第二個字母起到本域最後一個字符為止的字符串進行排序)。對於員工工資進行排 序,我們也使用了-k 3,3
,這是最準確的表述,表示我們“只”對本域進行排序,因為如果你省略了後面的3,就變成了我們“對第3個域開始到最後一個域位置的內容進行排序” 了。
uniq
Linux uniq命令用於檢查及刪除文本文件中重復出現的行列。
uniq可檢查文本文件中重復出現的行列。
語法
uniq [-cdu][-f<欄位>][-s<字符位置>][-w<字符位置>][--help][--version][輸入文件][輸出文件]
選項
對象 | 說明 |
---|---|
-c或--count | 在每列旁邊顯示該行重復出現的次數。 |
-d或--repeated | 僅顯示重復出現的行列。 |
-f<欄位>或--skip-fields=<欄位> | 忽略比較指定的欄位。 |
-s<字符位置>或--skip-chars=<字符位置> | 忽略比較指定的字符。 |
-u或--unique | 僅顯示出一次的行列。 |
-w<字符位置>或--check-chars=<字符位置> | 指定要比較的字符。 |
--help | 顯示幫助。 |
--version | 顯示版本信息。 |
wc
語法
wc [-clw][--help][--version][文件...]
選項
對象 | 說明 |
---|---|
-c或--bytes或--chars | 只顯示Bytes數。 |
-l或--lines | 只顯示行數。 |
-w或--words | 只顯示字數。 |
tr
tr 指令從標準輸入設備讀取數據,經過字符串轉譯後,將結果輸出到標準輸出設備。
語法
tr [-cdst][--help][--version][第一字符集][第二字符集]
tr [OPTION]…SET1[SET2]
選項
對象 | 說明 |
---|---|
-c, --complement | 反選設定字符。也就是符合 SET1 的部份不做處理,不符合的剩余部份才進行轉換 |
-d, --delete | 刪除指令字符 |
-s, --squeeze-repeats | 縮減連續重復的字符成指定的單個字符 |
-t, --truncate-set1 | 削減 SET1 指定範圍,使之與 SET2 設定長度相等 |
字符集合的範圍:
字符 | 說明 | 字符 | 說明 |
---|---|---|---|
\NNN | 八進制值的字符 NNN (1 to 3 為八進制值的字符) | \\ | 反斜杠 |
\a | Ctrl-G 鈴聲 | \b | Ctrl-H 退格符 |
\f | Ctrl-L 走行換頁 | \n | Ctrl-J 新行 |
\r | Ctrl-M 回車 | \t | Ctrl-I tab鍵 |
\v | Ctrl-X 水平制表符 | ||
CHAR1-CHAR2 | 字符範圍從 CHAR1 到 CHAR2 的指定,範圍的指定以 ASCII 碼的次序為基礎,只能由小到大,不能由大到小。 | [CHAR*] | 這是 SET2 專用的設定,功能是重復指定的字符到與 SET1 相同長度為止 |
[CHAR*REPEAT] | 這也是 SET2 專用的設定,功能是重復指定的字符到設定的 REPEAT 次數為止(REPEAT 的數字采 8 進位制計算,以 0 為開始) | [:alnum:] | 所有字母字符與數字 |
[:alpha:] | 所有字母字符 | [:blank:] | 所有水平空格 |
[:cntrl:] | 所有控制字符 | [:digit:] | 所有數字 |
[:graph:] | 所有可打印的字符(不包含空格符) | [:lower:] | 所有小寫字母 |
[:print:] | 所有可打印的字符(包含空格符) | [:punct:] | 所有標點字符 |
[:space:] | 所有水平與垂直空格符 | [:upper:] | 所有大寫字母 |
[:xdigit:] | 所有 16 進位制的數字 | [=CHAR=] | 所有符合指定的字符(等號裏的 CHAR,代表你可自訂的字符) |
join
Linux join命令用於將兩個文件中,指定欄位內容相同的行連接起來。
找出兩個文件中,指定欄位內容相同的行,並加以合並,再輸出到標準輸出設備。
語法
join [-i][-a<1或2>][-e<字符串>][-o<格式>][-t<字符>][-v<1或2>][-1<欄位>][-2<欄位>][--help][--version][文件1][文件2]
選項
對象 | 說明 |
---|---|
-a<1或2> | 除了顯示原來的輸出內容之外,還顯示指令文件中沒有相同欄位的行。 |
-e<字符串> | 若[文件1]與[文件2]中找不到指定的欄位,則在輸出中填入選項中的字符串。 |
-i或--igore-case | 比較欄位內容時,忽略大小寫的差異。 |
-o<格式> | 按照指定的格式來顯示結果。 |
-t<字符> | 使用欄位的分隔字符。 |
-v<1或2> | 跟-a相同,但是只顯示文件中沒有相同欄位的行。 |
-1<欄位> | 連接[文件1]指定的欄位。 |
-2<欄位> | 連接[文件2]指定的欄位。 |
實例
連接兩個文件。
為了清楚地了解join命令,首先通過cat命令顯示文件testfile_1和 testfile_2 的內容。
然後以默認的方式比較兩個文件,將兩個文件中指定字段的內容相同的行連接起來,在終端中輸入命令:
join testfile_1 testfile_2
首先查看testfile_1、testfile_2 中的文件內容:
$ cat testfile_1 #testfile_1文件中的內容
Hello 95 #例如,本例中第一列為姓名,第二列為數額
Linux 85
test 30
~$ cat testfile_2 #testfile_2文件中的內容
Hello 2005 #例如,本例中第一列為姓名,第二列為年份
Linux 2009
test 2006
然後使用join命令,將兩個文件連接,結果如下:
$ join testfile_1 testfile_2 #連接testfile_1、testfile_2中的內容
Hello 95 2005 #連接後顯示的內容
Linux 85 2009
test 30 2006
文件1與文件2的位置對輸出到標準輸出的結果是有影響的。
xargs
xargs命令是給其他命令傳遞參數的一個過濾器,也是組合多個命令的一個工具。它擅長將標準輸入數據轉換成命令行參數,xargs能夠處理管道或者stdin並將其轉換成特定命令的命令參數。xargs也可以將單行或多行文本輸入轉換為其他格式,例如多行變單行,單行變多行。xargs的默認命令是echo,空格是默認定界符。這意味著通過管道傳遞給xargs的輸入將會包含換行和空白,不過通過xargs的處理,換行和空白將被空格取代。xargs是構建單行命令的重要組件之一。
語法
xargs [ -p ] [ -t] [ -e[ EOFString ] ] [ -EEOFString ] [ -i[ ReplaceString ] ] [ -IReplaceString ] [ -l [ Number ] ] [ -L Number ] [ -n Number [ -x ] ] [ -s Size ] [ Command [ Argument ... ] ]
選項
對象 | 說明 |
---|---|
-0 | 如果輸入的stdin含有特殊字符,例如反引號`、反斜杠、空格等字符時,xargs可以將它還原成一般字符。為xargs的默認選項。 |
-e 、<flag>,-E <flag>,--eof=<eof-str> | eof是end of file string的意思。flag可以是一個字符串或者是由空格分隔的多個字符串,當xargs分析到這個flag時,就會停止工作。 |
-p | 當每次執行一個argument的時候詢問一次用戶。 |
-n <num> | 表示命令在執行的時候一次使用的argument的個數,由num指定,默認是用所有的參數。 |
-t | 表示先打印命令,然後再執行。 |
-a <file> | 從文件中讀入作為sdtin。 |
-i,-I | 其中-I某些Linux版本不支持。將xargs的輸出每一項參數,單獨賦值給後面的命令,參數需要用{}代替。見示例3。 |
-r | 或者--no-run-if-empty,當xargs的輸入為空的時候則停止xargs,不用再去執行後面的命令了,-r是xargs的默認選項。 |
-s <num> | 命令行的最大字符數,指的是xargs後面那個命令的最大命令行字符數,包括命令、空格和換行符。每個參數單獨傳入xargs後面的命令。 |
-L <line_num> | 設置標準輸入中最大的行數作為命令每一次執行的參數。 |
-d <delim>, --delimiter=<delim> | xargs處理標準輸入默認是按換行符和空格作為分隔符,輸出arguments的分隔符是空格,這裏修改xargs處理標準輸入時的分隔符。 |
-x | eXit的意思,主要是配合-s使用,當命令行字符數大於-s指定的數值時,退出xargs。 |
-P | 修改最大的進程數,默認是1,為0時候為as many as it can。該選項比較少用,目前還不清楚該用法。 |
實例
xargs用作替換工具,讀取輸入數據重新格式化後輸出。
定義一個測試文件,內有多行文本數據:
cat test.txt
a b c d e f g
h i j k l m n
o p q
r s t
u v w x y z
多行輸入單行輸出:
cat test.txt | xargs
a b c d e f g h i j k l m n o p q r s t u v w x y z
-n選項多行輸出:
cat test.txt | xargs -n3
a b c
d e f
g h i
......
-d選項可以自定義一個定界符:
echo "nameXnameXnameXname" | xargs -dX
name name name name
結合-n選項使用:
echo "nameXnameXnameXname" | xargs -dX -n2
name name
name name
讀取stdin,將格式化後的參數傳遞給命令
假設一個命令為 sk.sh 和一個保存參數的文件arg.txt:
#!/bin/bash
#sk.sh命令內容,打印出所有參數。
echo $*
arg.txt文件內容:
cat arg.txt
aaa
bbb
ccc
xargs的一個選項-I,使用-I指定一個替換字符串{},這個字符串在xargs擴展時會被替換掉,當-I與xargs結合使用,每一個參數命令都會被執行一次:
cat arg.txt | xargs -I {} ./sk.sh -p {} -l
-p aaa -l
-p bbb -l
-p ccc -l
復制所有圖片文件到 /data/images 目錄下:
ls *.jpg | xargs -n1 -I cp {} /data/images
xargs結合find使用
用rm 刪除太多的文件時候,可能得到一個錯誤信息:/bin/rm Argument list too long. 用xargs去避免這個問題:
find . -type f -name "*.log" -print0 | xargs -0 rm -f
xargs -0將\0作為定界符。
統計一個源代碼目錄中所有php文件的行數:
find . -type f -name "*.php" -print0 | xargs -0 wc -l
查找所有的jpg 文件,並且壓縮它們:
find . -type f -name "*.jpg" -print | xargs tar -czvf images.tar.gz
xargs其他應用
假如你有一個文件包含了很多你希望下載的URL,你能夠使用xargs下載所有鏈接:
cat url-list.txt | xargs wget -c
Linux 管道