Grep

區分命令而不是本地第二個發送器

  • November 6, 2018

認為

[root@iz2ze9wve43n2nyuvmsfx5z /]# find . -maxdepth 2 -type d  | ls
bin   dev  home  lib64       media  opt   root  sbin  sys  usr
boot  etc  lib   lost+found  mnt    proc  run   srv   tmp  var

ls 什麼也沒做,作為救援,我應該將它們重建為 ls 的列表

find . -type d | xargs ls
#millions of outputs

但是,grep 做得很好

[root@iz2ze9wve43n2nyuvmsfx5z /]# find . -maxdepth 2 -type d  | grep home
./home

我怎麼能區分一個命令不是作為第二個發射器出生的,而不是從底層理解而不是嘗試、錯誤測試和記憶。

要麼學習並記住各種程序的作用,要麼查看手冊頁。

的描述ls是:

列出有關文件的資訊(預設為目前目錄)

其中 FILEs 指的是概要:

ls

$$ OPTION $$…$$ FILE $$…

要記住的重要部分ls是它將生成有關您提供給它的“文件”的資訊 -在命令行上。該手冊沒有描述ls讀取任何輸入(例如,管道)的任何方式。

ls將手冊頁與手冊頁進行對比,手冊頁cat說:

$$ OPTION $$…$$ FILE $$… 將文件連接到標準輸出。沒有 FILE,或者當 FILE 為 - 時,讀取標準輸入。

有了cat,你可以cat /some/file或者你可以echo hi | cat

因此,在您的第一個範例中,

find . -maxdepth 2 -type d  | ls

find去並做了一些工作,並在其標準輸出上傳遞了一些(或沒有)目錄名稱,這成為了ls標準輸入,它ls立即被忽略了。由於您ls沒有列出要列出的文件,因此預設列出目前目錄。

在你的第二個例子中,

find . -type d | xargs ls

find去做(更多)工作,生成它在其標準輸出上找到的每個目錄,然後將其xargs作為標準輸入呈現。手冊頁xargs部分內容如下:

xargs 從標準輸入中讀取項目…並執行命令一次或多次…

給定標準輸入的輸入行數,因此根據需要呼叫thenls的次數。

同樣的想法轉化為您的第三個命令:

find . -maxdepth 2 -type d  | grep home

find將任何目錄名稱傳遞給grep的標準輸入;grep 的手冊頁再次部分說明:

grep 在命名的輸入文件中搜尋包含與給定 PATTERN 匹配的行。如果沒有指定文件,或者給出了文件“-”,則 grep 搜尋標準輸入。

管道的想法很簡單,但功能強大,您只需要知道程序產生什麼樣的輸出以及程序是否可以在其標準輸入上使用輸入。

grep是在這些情況下最常用的工具之一。您可以將其用作主要命令:

grep some-text file1 file2 file3 ...

在這種情況下,grep知道文件的名稱,或者您可以在其標準輸入上發送輸入:

cat file1 file2 file3 ... | grep some-text

…在這種情況下,grep 現在不再知道任何文件名(cat知道它們,然後將它們的內容生成到 stdout),因此現在 grep 無法知道哪些文件包含文本 - 只知道哪些行匹配。

將一堆命令連結在一起是很誘人的——通常被稱為“單行”,通常是半開玩笑的,因為“單行”可以變得足夠長,可以在終端視窗中將兩個第二行包裹起來——變成一個“管道”。在這裡,您必須確切地知道程序是如何產生和使用輸入的。

給定名為file1file2和的文件file3,您可以執行以下操作:

find . -name 'file*' | xargs cat

find當生成三個文件名作為標準輸出時,你不會感到驚訝——

file1 
file2 
file3

… xargs 編譯一個列表並將其發送到cat

cat file1 file2 file3

…誰看到這三個文件名並儘職盡責地將其內容轉儲到您的螢幕上。

當心,然後是一個名為“文件名here”的文件;上面的find命令會輸出:

file name here
file1
file2
file3

… xags 為它編譯一個列表cat-

cat file name here file1 file2 file3

cat抱怨(向標準錯誤!):

cat: file: 沒有這樣的文件或目錄

cat: name: 沒有這樣的文件或目錄

cat:這裡:沒有這樣的文件或目錄

… 後跟 file1、file2 和 file3 的內容。

您現在已準備好通過使用 NULL 作為文件名的分隔符find ... -exec等替代方法來避免這種情況。find ... -print0 | xargs -0 ...

引用自:https://unix.stackexchange.com/questions/480019