我知道从 bash 中读取命令的基本方法:
cal | while IFS= read -r line ; do
echo X${line}X
done
Run Code Online (Sandbox Code Playgroud)
但是,如果我想在循环中从多个文件/命令中读取一行怎么办?我试过命名管道,但他们只会吐出一行。
$ cal > myfifo &
$ IFS= read -r line < myfifo
[cal exits]
$ echo $line
February 2015
Run Code Online (Sandbox Code Playgroud)
所以我真正想要的是:
while [all pipes are not done]; do
IFS=
read line1 < pipe1 # reading one line from this one
read line2 < pipe2 # and one line from this one
read line3 < pipe3 # and one line from this one
print things with $line1 $line2 and $line3
done
Run Code Online (Sandbox Code Playgroud)
我正在尝试做的大图是从 cal 处理三个月不同的时间来进行一些着色以与 Conky 一起使用。老实说,这有点像剃牦牛毛,所以在这一点上已经成为学术和“学习经验”。
paste将是最整洁的方式来做到这一点。但是,使用 bash 文件描述符和进程替换:
exec 3< <(cal 1 2015)
exec 4< <(cal 2 2015)
exec 5< <(cal 3 2015)
while IFS= read -r -u3 line1; do
IFS= read -r -u4 line2
IFS= read -r -u5 line3
printf "%-25s%-25s%-25s\n" "$line1" "$line2" "$line3"
done
exec 3<&-
exec 4<&-
exec 5<&-
Run Code Online (Sandbox Code Playgroud)
January 2015 February 2015 March 2015
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 6 7
4 5 6 7 8 9 10 8 9 10 11 12 13 14 8 9 10 11 12 13 14
11 12 13 14 15 16 17 15 16 17 18 19 20 21 15 16 17 18 19 20 21
18 19 20 21 22 23 24 22 23 24 25 26 27 28 22 23 24 25 26 27 28
25 26 27 28 29 30 31 29 30 31
Run Code Online (Sandbox Code Playgroud)
您可以使用paste组合输出,然后按行读取:
paste -d $'\n' <(foo) <(bar) <(cat baz) | while IFS= read -r line1
do
IFS= read -r line2 || break
IFS= read -r line3 || break
# ..
done
Run Code Online (Sandbox Code Playgroud)