2013-07-25 71 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

我看,这是正确的,我不知道大括号在那里。 –