考虑从管道中获取结果:
find .
现在我想在管道后面的第二个命令中访问实际管道(输入)的内容,然后例如打印两次。
find . | printf $arg$arg\n
#each filename would be printed twice per line
请注意,问题不是要打印两次从管道中获取的任何内容,我知道如何使用 bash for循环或编写可以完成上述操作的脚本。如何让 $arg 在内联脚本中快速使用它?
$0 和 $1 不像在脚本文件中那样工作。
忽略文件名包含换行符的可能性,您可以sed
按照pringley在他的回答中建议的那样使用中建议的那样使用,或者您可以使用以下命令创建while
循环:read
find . |
while read -r line
do
echo "$line$line"
done
(-r
用于“原始”输入;它停止 shell 扩展输入中的反斜杠转义序列,并且是read
shell 中命令的标准 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
似乎都这样做了。
简短回答:您可以使用 sed 将每个文件打印两次:
find . | sed 's/.*/& &/'
Sed 可以在输入行时对其进行编辑。上面的命令说s
(替代).*
(整行)& &
(用它自己,两次)。
更长的答案:当您将一个程序传输到另一个程序时,您将第一个程序的标准输出流连接到第二个程序的标准输入流。第一个程序打印的任何内容都将被视为第二个程序的输入。
不幸的是,对于您的示例,输入不是逐行块很好地映射到假设$args
变量。它来自一个巨大的整体流。如果你想打印流的每一行两次,你可以使用 sed (它是一个流编辑器),但它只是逐行替换。
find . | xargs -I{} printf "%s%s\n" {} {}