2013-07-25 74 views
4

考慮從管道結果:獲得從管道參數

find . 

現在我想在管道後面的第二個命令訪問什麼是真正的管道(inputed),然後例如打印兩次。

find . | printf $arg$arg\n 
#each filename would be printed twice per line 

請注意,這個問題是不是問什麼打印一次從管道得到了兩次,我知道如何使用bash 循環或編寫一個腳本,可以實現提及。 如何讓$ arg在內聯腳本中快速使用它?

$ 0和$ 1在腳本文件中不起作用。

回答

5

簡短的回答:可以打印每一個文件兩次使用SED:因爲它們是輸入

find . | sed 's/.*/& &/' 

桑達可以編輯線。上述命令表示s(替代).*(整行)& &(本身兩次)。

較長的答案:當你管一個程序到另一個,你要連接的第一個程序的標準輸出流到第二程序的標準輸入流。第一個程序打印的任何東西都將被視爲第二個程序的輸入。

對於您的示例而言,不幸的是,輸入不是逐行塊,很好地映射到假設的$args變量。它來到一個巨大的整體流。如果你想打印兩行流,你可以使用sed(這是一個Stream EDitor),但它只是逐行替換。

6

忽略的可能性,文件名包含換行符,您可以使用sedpringley表明他answer,或者你可以創建一個while循環與read命令:

find . | 
while read -r line 
do 
    echo "$line$line" 
done 

(該-r是「生'輸入;它停止在輸入中擴展反斜槓轉義序列的外殼,並且是外殼中的read命令的標準POSIX特徵。)

由於您提到bash,所以yo u能避免在文件名中的換行符問題通過使用find . -print0選項終止一個空字節('\0'在C)每個名稱,而不是一個換行符,然後使用:

find . -print0 | 
while read -r -d '' line 
do 
    echo "X${line}${line}X" 
done 

-d ''替換正常的換行符定界符與字符串參數的第一個字符,但字符串是空的,所以第一個字符是唯一的字符是空字節。

沒有一個簡單的方法(也沒有,據我所知,硬路)使用的線沿線的一個for循環:

for line in $(find .) 
do 
    echo "X${line}${line}X" 
done 

與空間工作可靠的名稱,或換行符。

通常,您可能需要使用xargs命令。這讀取標準輸入並使用從標準輸入讀取的內容作爲命令的參數創建命令行。

find . | xargs wc -l 

或者,用換行和空間安全(默認情況下,xargs在空格,製表符和換行符分割參數):

find . -type f -print0 | xargs -0 wc -l 

有很多的選項,你可以申請xargs - 尤其是GNU版本。

但是,你也有選項find在很大程度上使xargs冗餘:

find . -type f -exec wc -l {} + 

基本上做相同的工作作爲find . -print0 | xargs -0 wc -l命令。一個區別是,如果find的輸出中沒有文件,那麼使用-exec完全不會執行wc,而默認情況下,xargs將執行一次(沒有文件名參數;用於POSIX合規性)。使用GNU xargs,您可以使用-r--no-run-if-empty來停止這種情況。無論如何,Mac OS X xargs似乎都這樣做。

3
find . | xargs -I{} printf "%s%s\n" {} {} 
+0

考慮'find。 | xargs -I {} printf「%s之間%s \ n」{} {}',試試吧,它會打印什麼? –

+1

如果你沒有在'{}'和'{}'之間留出空格,我希望它能打印出「./file./file」。如果*有*空格,我期望「./file」./file「 –

+0

我看,這是正確的,我不知道大括號在那裏。 –