在bash中一次读取多个文件一行

Gre*_*ell 5 bash read

我知道从 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 一起使用。老实说,这有点像剃牦牛毛,所以在这一点上已经成为学术和“学习经验”。

gle*_*man 7

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)

  • 或者 `...done 3&lt; &lt;(cal...) 4&lt; &lt;(cal...) 5&lt; &lt;(cal...)` (2认同)

mur*_*uru 2

您可以使用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)