11

考虑从管道中获取结果:

find .

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

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

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

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

4

3 回答 3

10

忽略文件名包含换行符的可能性,您可以sed按照pringley在他的回答中建议的那样使用中建议的那样使用,或者您可以使用以下命令创建while循环:read

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

-r用于“原始”输入;它停止 shell 扩展输入中的反斜杠转义序列,并且是readshell 中命令的标准 POSIX 功能。)

既然您提到了,您可以通过使用以空字节终止每个名称bash的选项来避免文件名中的换行符问题(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

您可以应用很多选项xargs——尤其是 GNU 版本。

但是,您还可以选择在find很大程度上使xargs冗余:

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

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

于 2013-07-25T02:23:07.533 回答
9

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

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

Sed 可以在输入行时对其进行编辑。上面的命令说s(替代).*(整行)& &(用它自己,两次)。

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

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

于 2013-07-25T00:52:25.973 回答
4
find . | xargs -I{} printf "%s%s\n" {} {}
于 2013-07-25T03:38:36.853 回答