Linux:管線命令

http://blog.csdn.net/pipisorry/article/details/39760961linux

當Linux執行一個程序的時候,會自動打開三個流,標準輸入(standard input),標準輸出(standard output),標準錯誤(standard error)。好比說你打開命令行的時候,默認狀況下,命令行的標準輸入鏈接到鍵盤,標準輸出和標準錯誤都鏈接到屏幕。git

<符號改變標準輸入正則表達式

好比cat命令,它能夠從標準輸入讀入文本流,並輸出到標準輸出:算法

$cat < a.txtshell

咱們將cat標準輸入指向a.txt,文本會從文件流到cat,而後再輸出到屏幕上。segmentfault

同時從新定向標準輸出
bash

$cat < a.txt > b.txtless

使用>&來同時從新定向標準輸出和標準錯誤。工具

若是隻想從新定向標準錯誤,可使用2>。post

管線命令 (pipe)

管線命令在 bash 的連續的處理程序中是至關重要的,在 log file 的分析當中也是至關重要的一環。

Note: 管線命令前面命令的輸出可使用{}收集。

擷取命令: cut, grep
排序命令: sort, uniq, wc
雙向重導向: tee
字符轉換命令: tr, col, join, paste, expand
分割命令: split
參數代換: xargs
關於減號 - 的用途

皮皮blog



擷取命令: cut, grep

linux cut命令

$ cut -d'分隔字符' -f fields &lt;==用於有特定分隔字符

$ cut -c 字符區間 &lt;==用於排列整齊的訊息

選項與參數:
-d  :後面接分隔字符。與 -f 一塊兒使用;
-f  :依據 -d 的分隔字符將一段訊息分區成爲數段,用 -f 取出第幾段的意思;
-c  :以字符 (characters) 的單位取出固定字符區間;這樣不就是對字符串取子串操做麼

去除字符串前兩位字符

find . -size +100M ! -path *git* | cut -c 3-

linux grep命令

做用
Linux系統中grep命令是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹 配的行打印出來。grep全稱是Global Regular Expression Print,表示全局正則表達式版本,它的使用權限是全部用戶。

有一點要注意,您必需提供一個文件過濾方式(搜索所有文件的話用 *)。若是您忘了,’grep’會一直等着,直到該程序被中斷。若是您遇到了這樣的狀況,按 <CTRL c> ,而後再試。

grep 則是分析一行訊息, 若當中有咱們所須要的信息,就將該行拿出來~

格式

-h:查詢多文件時不顯示文件名。
-l:查詢多文件時只輸出包含匹配字符的文件名。
-s:不顯示不存在或無匹配文本的錯誤信息。$ grep [-acinv] [--color=auto] '搜尋字串' filename
選項與參數:
-a :將 binary 文件以 text 文件的方式搜尋數據
-c :計算找到 '搜尋字串' 的次數,只輸出匹配行的計數
-i :忽略大小寫的不一樣,因此大小寫視爲相同(只適用於單字符)
-n :順便輸出行號,顯示匹配行及行號。
-v :反向選擇,亦即顯示出沒有 '搜尋字串' 內容的那一行!
--color=auto :能夠將找到的關鍵字部分加上顏色的顯示喔!

pattern正則表達式主要參數:
\: 忽略正則表達式中特殊字符的原有含義。
^:匹配正則表達式的開始行。
$: 匹配正則表達式的結束行。
\<:從匹配正則表達式的行開始。
\>:到匹配正則表達式的行結束。

\< 和 \> 分別標註單詞的開始與結尾。例如:
grep man * 會匹配 ‘Batman’、’manic’、’man’等,
grep ‘\<man’ * 匹配’manic’和’man’,但不是’Batman’,
grep ‘\<man\>’ 只匹配’man’,而不是’Batman’或’manic’等其餘的字符串。[ ]:單個字符,如[A]即A符合要求 。
[ - ]:範圍,如[A-Z],即A、B、C一直到Z都符合要求 。
。:全部的單個字符。應該是英文句號?
* :有字符,長度能夠爲0。

下面還有一些有意思的命令行參數:
grep -l pattern files :只列出匹配的文件名,
grep -L pattern files :列出不匹配的文件名,
grep -w pattern files :只匹配整個單詞,而不是字符串的一部分(如匹配’magic’,而不是’magical’),
grep -C number pattern files :匹配的上下文分別顯示[number]行,
grep pattern1 | pattern2 files :顯示匹配 pattern1 或 pattern2 的行,
grep pattern1 files | grep pattern2 :顯示既匹配 pattern1 又匹配 pattern2 的行。

4.grep命令使用簡單實例

$ grep ‘test’ d*
顯示全部以d開頭的文件中包含 test的行。
$ grep ‘test’ aa bb cc
顯示在aa,bb,cc文件中匹配test的行。
$ grep ‘[a-z]\{5\}’ aa
顯示全部包含每一個字符串至少有5個連續小寫字符的字符串的行。
$ grep ‘w\(es\)t.*\1′ aa
若是west被匹配,則es就被存儲到內存中,並標記爲1,而後搜索任意個字符(.*),這些字符後面緊跟着 另一個es(\1),找到就顯示該行。若是用egrep或grep -E,就不用」\」號進行轉義,直接寫成’w(es)t.*\1′就能夠了。

5.grep命令使用複雜實例

假設您正在’/usr/src/Linux/Doc’目錄下搜索帶字符 串’magic’的文件:
$ grep magic /usr/src/Linux/Doc/*
sysrq.txt:* How do I enable the magic SysRQ key?
sysrq.txt:* How do I use the magic SysRQ key?
其中文件’sysrp.txt’包含該字符串,討論的是 SysRQ 的功能。
默認狀況下,’grep’只搜索當前目錄。若是 此目錄下有許多子目錄,’grep’會以以下形式列出:
grep: sound: Is a directory
這可能會使’grep’ 的輸出難於閱讀。這裏有兩種解決的辦法:
明確要求搜索子目錄:grep -r
或忽略子目錄:grep -d skip
若是有不少 輸出時,您能夠經過管道將其轉到’less’上閱讀:
$ grep magic /usr/src/Linux/Documentation/* | less
這樣,您就能夠更方便地閱讀。

grep字符串搜索算法

grep速度快的一個重要緣由是使用了Boyer-Moore算法做爲字符串搜索算法

[爲何GNU grep如此之快?]

grep之字符串搜索算法Boyer-Moore由淺入深(比KMP快3-5倍)

[grep之字符串搜索算法Boyer-Moore由淺入深]

皮皮Blog



排序命令: sort, uniq, wc

linux sort命令

排序的字符與語系的編碼有關,所以, 若是您須要排序時,建議使用 LANG=C 來讓語系統一,數據排序比較好一些。

$ sort [-fbMnrtuk] [file or stdin]
選項與參數:
-f  :忽略大小寫的差別,例如 A 與 a 視爲編碼相同;
-b  :忽略最前面的空白字符部分;
-M  :以月份的名字來排序,例如 JAN, DEC 等等的排序方法;
-n  :使用「純數字」進行排序(默認是以文字體態來排序的);
-r  :反向排序;
-u :就是 uniq ,相同的數據中,僅出現一行表明;
-t  :分隔符號,默認是用 [tab] 鍵來分隔;
-k  :以那個區間 (field) 來進行排序的意思

linux uniq命令

將重複的數據僅列出一個顯示

[dmtsai@study ~]$ uniq [-ic]
選項與參數:
-i  :忽略大小寫字符的不一樣;
-c  :進行計數

Note: 特別要注意的地方: 'uniq'  does not detect repeated lines unless they are adjacent.  You may want to sort the input first, or use 'sort -u' without  'uniq'.   Also,  comparisons honor the rules specified by 'LC_COLLATE'.

也就是在使用uniq以前要進行排序,不然相隔的相同字符不會去重。這樣的話,直接使用sort -nu最好了。

pipi@pipicmp:~/files/DATASETS/tianchi/ccf_data_revised$ cat ccf_online_stage1_train.csv | cut -d ',' -f 2 | uniq | sort -n | head
10001
10001
10001...
10001
pipi@pipicmp:~/files/DATASETS/tianchi/ccf_data_revised$ cat ccf_online_stage1_train.csv | cut -d ',' -f 2 | sort -n | uniq | head
10001
10002
10003
10004...
10009
10010

linux wc命令

要知道文件裏面有多少字?多少行?多少字符?

$ wc [-lwm]
選項與參數:
-l  :僅列出行;
-w  :僅列出多少字(英文單字);
-m  :多少字符;

統計項目中的代碼行數cloc

cloc可以統計包括:代碼行數、註釋、空行、文件大小等數據。另外,還支持對軟件開發項目的各個開發階段的工數、成本、質量指標等進行分析和預測。

$ sudo apt-get install cloc

SocialNetworks$ cloc .

[cloc網站]

直接寫簡單的能夠這樣:

find . \( -path ./tmp_data -o -path ./gowalla-exp \) -prune -o \( -name '*.pyc' -o -name '*.py' -type f \) -print | xargs -0 cat | grep -v -e ^$ -e ^\s*\#.*$ | wc -l | more

[怎麼統計一個工程的代碼行數]

[一句shell命令搞定代碼行數統計]

皮皮blog



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

tr

tr 能夠用來刪除一段訊息當中的文字,或者是進行文字訊息的替換!
$ tr [-ds] SET1 ...
選項與參數:
-d  :刪除訊息當中的 SET1 這個字串;
-s  :取代掉重複的字符!

範例一:將 last 輸出的訊息中,全部的小寫變成大寫字符:
$ last  tr '[a-z]' '[A-Z]'
# 事實上,沒有加上單引號也是能夠執行的,如:「 last | tr [a-z] [A-Z] 」
範例二:將 /etc/passwd 輸出的訊息中,將冒號 (:) 刪除
$ cat /etc/passwd | tr -d ':'
範例三:將 /etc/passwd 轉存成 dos 斷行到 /root/passwd 中,再將 ^M 符號刪除
$ cp /etc/passwd ~/passwd && unix2dos ~/passwd
$ file /etc/passwd ~/passwd
/etc/passwd:         ASCII text
/home/dmtsai/passwd: ASCII text, with CRLF line terminators  &lt;==就是 DOS 斷行
$ cat ~/passwd | tr -d '\r' > ~/passwd.linux
# 那個 \r 指的是 DOS 的斷行字符,關於更多的字符,請參考 man tr
$ ll /etc/passwd ~/passwd*
-rw-r--r--. 1 root   root   2092 Jun 17 00:20 /etc/passwd
-rw-r--r--. 1 dmtsai dmtsai 2133 Jul  9 22:13 /home/dmtsai/passwd
-rw-rw-r--. 1 dmtsai dmtsai 2092 Jul  9 22:13 /home/dmtsai/passwd.linux
# 處理事後,發現文件大小與本來的 /etc/passwd 就一致了!

其實這個指令也能夠寫在「正則表達式」裏頭!由於他也是由正則表達式的方式來取代數據的! 以上面的例子來講,使用 [] 能夠設置一串字呢!也經常用來取代文件中的怪異符號! 例如上面第三個例子當中,能夠去除 DOS 文件留下來的 ^M 這個斷行的符號!這東西至關的有用!相信處理 Linux & Windows 系統中的人們最麻煩的一件事就是這個事情啦!亦便是 DOS 下面會自動的在每行行尾加入 ^M 這個斷行符號!這個時候除了之前講過的 dos2unix 以外,咱們也可使用這個 tr 來將 ^M 去除! ^M 可使用 \r 來代替之!

join

join 看字面上的意義 (加入/參加) 就能夠知道,他是在處理兩個文件之間的數據, 並且,主要是在處理「兩個文件當中,有 "相同數據" 的那一行,纔將他加在一塊兒」的意思。

paste

linux中按列合併文件的命令。相對於 join 必需要比對兩個文件的數據相關性, paste 就直接「將兩行貼在一塊兒,且中間以 [tab] 鍵隔開」而已!簡單的使用方法:

$ paste [-d] file1 file2
選項與參數:
-d  :後面能夠接分隔字符。默認是以 [tab] 來分隔的!
-   :若是 file 部分寫成 - ,表示來自 standard input 的數據的意思。

expand

將 [tab] 按鍵轉成空白鍵$ expand [-t] file

選項與參數:
-t  :後面能夠接數字。通常來講,一個 tab 按鍵能夠用 8 個空白鍵取代。也能夠自行定義一個 [tab] 按鍵表明多少個字符呢!

皮皮blog



分區命令: split

split 能夠幫你將一個大文件,依據文件大小或行數來分區,就能夠將大文件分區成爲小文件了!

在 Linux 下面要將文件分區的話,那麼就使用 -b size 來將一個分區的文件限制其大小,若是是行數的話,那麼就使用 -l line 來分區!

$ split [-bl] file PREFIX
選項與參數:
-b  :後面可接欲分區成的文件大小,可加單位,例如 b, k, m 等;
-l  :以行數來進行分區。
PREFIX :表明前置字符的意思,可做爲分區文件的前導文字。

範例一:個人 /etc/services 有六百多K,若想要分紅 300K 一個文件時?
[dmtsai@study ~]$ cd /tmp; split -b 300k /etc/services services
[dmtsai@study tmp]$ ll -k services*
-rw-rw-r--. 1 dmtsai dmtsai 307200 Jul  9 22:52 servicesaa
-rw-rw-r--. 1 dmtsai dmtsai 307200 Jul  9 22:52 servicesab
-rw-rw-r--. 1 dmtsai dmtsai  55893 Jul  9 22:52 servicesac
# 只要寫上前導文字,小文件就會以 xxxaa, xxxab, xxxac 等方式來建立小文件的!

範例二:如何將上面的三個小文件合成一個文件,文件名爲 servicesback
[dmtsai@study tmp]$ cat services* >> servicesback
# 用數據流重導向就好

範例三:使用 ls -al / 輸出的信息中,每十行記錄成一個文件
[dmtsai@study tmp]$ ls -al / &#124; split -l 10 - lsroot
[dmtsai@study tmp]$ wc -l lsroot*
  10 lsrootaa
  10 lsrootab
   4 lsrootac
  24 total
# 重點在那個 - 啦!通常來講,若是須要 stdout/stdin 時,但恰恰又沒有文件,# 有的只是 - 時,那麼那個 - 就會被當成 stdin 或 stdout ~


參數代換: xargs

{非管道命令變成管道命令!}

以字面上的意義來看, x 是加減乘除的乘號,args 則是 arguments (參數) 的意思,因此就是在產生某個指令的參數的意思! xargs 能夠讀入 stdin 的數據,而且以空白字符或斷行字符做爲分辨,將 stdin 的數據分隔成爲 arguments 。 由於是以空白字符做爲分隔,因此,若是有一些文件名或者是其餘意義的名詞內含有空白字符的時候, xargs 可能就會誤判了~

-0  :若是輸入的 stdin 含有特殊字符,例如 `, \, 空白鍵等等字符時,這個 -0 參數能夠將他還原成通常字符。這個參數能夠用於特殊狀態喔!If there are blank spaces or characters (including newlines) many commands will not work. This option take cares of file names with blank space.-I (指定了管道前命令做爲參數所應該在管道後面命令的位置。e.g. | xargs -I _ mv _ /tmp/c). Replace occurrences of replace-str in the initial-arguments with names read from standard input.  Also, unquoted blanks do not terminate input items; instead the separator is the newline character.$ xargs [-0epn] command
選項與參數:-e  :這個是 EOF (end of file) 的意思。後面能夠接一個字串,當 xargs 分析到這個字串時,就會中止繼續工做!
-p  :在執行每一個指令的 argument 時,都會詢問使用者的意思;
-n  :後面接次數,每次 command 指令執行時,要使用幾個參數的意思。-I當 xargs 後面沒有接任何的指令時,默認是以 echo 來進行輸出!

示例

$ find /usr/sbin -perm /7000 | xargs ls -l

$ find . -name "*.bak" -print0 | xargs -0 -I {} mv {} ~/old.files

出錯:xargs: cat: terminated by signal 13

find . \( -name '*.pyc' -o -name '*.py' -type f \) -print | xargs cat

緣由:

[[Linux]若是管道被接受方關閉]

可能的解決:

修改爲find . -type f -exec grep "something" {} \; -quit
This is how it works:The -exec will work when the -type f will be true. And because grep returns 0 (success/true) when the -exec grep "something" has a match, the -quit will be triggered.

[bash find xargs grep only single occurence]

皮皮blog


減號 - 的用途

在管線命令當中,經常會使用到前一個指令的 stdout 做爲此次的 stdin , 某些指令須要用到文件名稱 (例如 tar) 來進行處理時,該 stdin 與 stdout 能夠利用減號 "-" 來替代, 舉例來講:

mkdir /tmp/homeback
tar -cvf - /home &#124; tar -xvf - -C /tmp/homeback

上面這個例子是說:「我將 /home 裏面的文件給他打包,但打包的數據不是紀錄到文件,而是傳送到 stdout; 通過管線後,將 tar -cvf - /home 傳送給後面的 tar -xvf - 」。後面的這個 - 則是取用前一個指令的 stdout, 所以,咱們就不須要使用 filename 了!

皮皮blog

from:http://blog.csdn.net/pipisorry/article/details/39760961

ref: 鳥哥的linux私房菜

相關文章
相關標籤/搜索