【Linux】- 對find,xargs,grep和管道的一些理解
問題
相信大家都知道在目錄中搜索含有固定字串檔案的命令:
find . -name '*.py' |xargs grep test
剛開始的時候,我不熟悉xargs
命令,所以直接使用的命令是:
find . -name '*.py' |grep test
結果並不是自己所期望的。此命令只是找出檔名中包含"test"
的檔案。
本文旨在揭示xargs究竟做了什麼,使得結果不一樣。
引數與標準輸入
這兩個詞在Linux命令中是很常見的。但是引數和標準輸入其實是有區別的。我們日常使用的很多命令,例如:ls -lah .
中。l
、 a
、 h
、.
ls
的引數。至於標準輸入,可以說它是某種流資料。而通常來講標準輸入的流資料來源就是我們的終端輸入。在Linux命令中,有些命令可以接收標準輸入,有些是不能的。像上面的ls
,就是隻能接收引數,不能接收標準輸入。像cat
命令或echo
命令,這些是可以的。
怎麼分辨一個命令可不可以接收標準輸入?很簡單,當你敲完命令回車後,終端會等待接收你的輸入,例如當你在終端輸入cat
後,終端會等待你輸入字元,當你輸入一些字元後,然後按Ctrl-C
傳送終止符號。這時cat
命令接收標準輸入完畢,執行命令,也就是將剛才鍵入的內容輸出的標準輸出上(螢幕)。
管道
管道的作用是將前面命令的標準輸出作為後面命令的標準輸入。這裡要注意,後面的命令接收的是標準輸入,所以如果命令不支援接收標準輸入,那麼就不能直接使用管道,例如常用的ls
[command] | ls
是不能使用的。而命令如echo
或cat
就可以。那麼肯定有方法來實現這些不能使用標準輸入的命令與管道結合,這時候xargs
便出場了。
xargs命令
xargs
命令通俗來講就是將標準輸入轉成各種格式化的引數,所以命令[command 1] | xargs [command 2]
就是將command 1
的標準輸出結果,通過管道|
變成xargs
的標準輸入,然後xargs
再將此標準輸入變成引數,傳給[command 2]
。這樣一來,通過xargs
命令,我們便可以在管道後面使用那些不接收標準輸入的命令了。例如[command 1]|xargs ls
find與grep
有了以上的知識點,到這裡終於可以解答最開始的問題了。為什麼命令:
find . -name '*.py' |grep test
和
find . -name '*.py' |xargs grep test
的結果是不一樣的了。
我們首先來檢視grep手冊。通過man grep
命令:
DESCRIPTION grep searches the named input FILEs (or standard input if no files are named, or if a single hyphen-minus (-) is given as file name) for lines containing a match to the given PATTERN.
By default, grep prints the matching lines.
可以看到grep是支援標準輸入的。
假設目錄存在如下檔案:
$ ls Altitest.py python.py runora.py test.py TransferFile.py
那麼對於第一個命令:find . -name '*.py' |grep test
,是將前面命令的標準輸出作為標準輸入傳給了grep test
,那麼grep
是從這些標準輸入尋找test
字元,也就是檔名組成的字元流。
$ find . -name '*.py' |grep test ./Altitest.py ./test.py
可以看到最終選擇出的是這些檔名。
而對於第二個命令:find . -name '*.py' |xargs grep test
,通過xargs
,find
得到的檔名成為了引數傳給後面的grep
,那麼這時候這些檔名就是實實在在的檔案標識,grep
接收後會按正常的使用方式在各檔案中搜尋字串。
#find . -name '*.py' |xargs grep test ./runora.py:testConn = cx_Oracle.connect('user/[email protected]') ./runora.py:testCursor = testConn.cursor() ./runora.py:testCursor.execute("select * from table") ./runora.py:rows = testCursor.fetchall() ./runora.py:testCursor.close() ./runora.py:testConn.close()
到這裡算是將find
,grep
,xargs
和管道的作用理解清楚了。
轉自:http://fatmouse.xyz/2016/05/10/2016-05-10-find-grep-xargs-and-pipe/