从管道获取参数

时间:2013-07-25 00:35:08

标签: bash pipe xargs

考虑从管道获得结果:

find .

现在我想在管道后面的第二个命令中访问实际管道(输入)的内容,然后再打印两次。

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

请注意,问题不是要求打印一次从管道输出两次,我知道如何使用bash 进行循环或编写一个可以完成上述操作的脚本。 如何让$ arg 在内联脚本中快速使用它?

$ 0和$ 1不像脚本文件那样工作。

3 个答案:

答案 0 :(得分:8)

忽略文件名包含换行符的可能性,您可以在pringley中使用sed作为answer建议,或者您可以使用{{创建while循环1}}命令:

read

find . | while read -r line do echo "$line$line" done 用于'raw'输入;它会停止shell在输入中扩展反斜杠转义序列,并且是shell中-r命令的标准POSIX功能。)

由于您提到read,您可以使用bash选项通过空字节(C中为find . -print0)来终止每个名称,从而避免文件名中的换行问题,而不是换行,然后使用:

'\0'

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 - 尤其是GNU版本。

但是,您还可以选择xargs,使find多余:

xargs

find . -type f -exec wc -l {} + 命令的工作基本相同。一个区别是,如果find . -print0 | xargs -0 wc -l的输出中没有文件,那么使用find根本不会执行-exec,而默认情况下,wc会执行它一次(没有文件名参数;这是为了符合POSIX)。使用GNU xargs,您可以使用xargs-r来阻止这种情况发生。无论如何,Mac OS X --no-run-if-empty似乎都是这样做的。

答案 1 :(得分:5)

简答:您可以使用sed打印每个文件两次:

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

Sed可以在输入时编辑行。上面的命令显示s(替代).*(整行)& &(自身两次)。

更长的答案:当您将一个程序传输到另一个程序时,您将第一个程序的标准输出流连接到第二个程序&#39 ; s 标准输入流。第一个程序打印的任何内容都将被视为第二个程序的输入。

不幸的是,对于您的示例,输入并不是逐行排列的,可以很好地映射到假设的$args变量。它有一个巨大的整体流。如果你想打印两次流的每一行,你可以使用sed(这是一个Stream EDitor),但它只是逐行替换。

答案 2 :(得分:4)

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