下面的Perl脚本(my.pl)既可以从命令行参数中的文件读取,也可以从标准输入(STDIN)读取:
while (<>) {
print($_);
}
Perl my.pl将从标准输入中读取,而Perl my.pl .txt将从a.txt中读取。这很方便。
Bash中也有类似的功能吗?
下面的Perl脚本(my.pl)既可以从命令行参数中的文件读取,也可以从标准输入(STDIN)读取:
while (<>) {
print($_);
}
Perl my.pl将从标准输入中读取,而Perl my.pl .txt将从a.txt中读取。这很方便。
Bash中也有类似的功能吗?
当前回答
这个很容易在终端上使用:
$ echo '1\n2\n3\n' | while read -r; do echo $REPLY; done
1
2
3
其他回答
请尝试以下代码:
while IFS= read -r line; do
echo "$line"
done < file
也许最简单的解决方案是使用合并重定向操作符重定向标准输入:
#!/bin/bash
less <&0
标准输入是文件描述符0。上面的代码将通过管道传输到bash脚本的输入发送到less的标准输入中。
阅读有关文件描述符重定向的更多信息。
每当IFS中断输入流时,回显解决方案就添加新行。@fgm的回答可以稍微修改一下:
cat "${1:-/dev/stdin}" > "${2:-/dev/stdout}"
Use:
for line in `cat`; do
something($line);
done
问题中的Perl循环从命令行上的所有文件名参数读取,如果没有指定文件,则从标准输入读取。如果没有指定文件,我看到的答案似乎都在处理单个文件或标准输入。
虽然经常被嘲笑为UUOC(无用地使用猫),但有时猫是工作的最佳工具,这是有争议的:
cat "$@" |
while read -r line
do
echo "$line"
done
唯一的缺点是它创建了一个在子shell中运行的管道,因此while循环中的变量赋值之类的东西在管道之外是不可访问的。bash的方法是进程替换:
while read -r line
do
echo "$line"
done < <(cat "$@")
这使得while循环在主shell中运行,因此在循环中设置的变量可以在循环外访问。