【问题标题】:Bash: Two for loops at once?Bash:一次有两个 for 循环?
【发布时间】:2019-01-25 02:14:23
【问题描述】:

我完全不知道该怎么做。

我有两个文本文件,FILE1FILE2

我想同时为每个文件运行一个 for 循环并显示 内容彼此相邻。

例如,

for $i in $(cat FILE1); do echo $i; done

for $j in $(cat FILE2); do echo $j; done

我想将这两个命令结合起来,这样我就可以同时运行这两个文件并得到类似$i $j的输出

【问题讨论】:

标签: linux bash shell ubuntu for-loop


【解决方案1】:

解决方案 1

使用paste 命令

paste FILE1 FILE2

Details for paste command

Another resource

解决方案 2

如果它们的行数相同,您可以这样做。

#!/bin/bash
t=$(cat FILE1 | wc -l)
for i in `seq 1 $t`;
do
    cat FILE1|head -n $i|tail -n 1
    cat FILE2|head -n $i|tail -n 1
done

你可以将它扩展到你想要的不等行数。

【讨论】:

  • 解决方案 2 效率极低,永远不应该使用。
【解决方案2】:

您根本不应该使用for 循环;见Bash FAQ 001。而是在一个 while 循环中使用两个 read 命令。

while IFS= read -r line1 && IFS= read -r line2 <&3; do
  printf '%s | %s\n' "$line1" "$line2"
done < FILE1 3< FILE2

每个read 命令都从一个单独的文件描述符中读取。在这个版本中,当两个文件中较短的一个用完时,循环将退出。

【讨论】:

    【解决方案3】:

    这里有两个不同的问题。其他答案解决了如何在 2 列中显示文件内容的问题。同时运行两个循环(这是解决第一个问题的错误方法)可以通过异步运行它们来完成:for i in ${seqi?}; do ${cmdi?}; done &amp; for j in ${seqj?}; do ${cmdj?}; done &amp; wait

    虽然你也可以用类似的方式实现paste -d ' ' file1 file2

    while read line_from_file1; p=$?; read line_from_file2 <&3 || test "$p" = 0; do
        echo "$line_from_file1" "$line_from_file2"
    done < file1 3< file2
    

    【讨论】:

    • 我刚刚注意到@chepner 提供了几乎相同的解决方案,但我不会删除我的,因为它解决了文件具有不同行长的问题。但这完全是一种 hack,永远不应该这样做。
    【解决方案4】:

    另一个选项,在bash v4+ 中是将两个文件读入 2 个数组,然后并排回显数组元素:

    # Load each file into its own array
    readarray -t f1 < file1
    readarray -t f2 < file2
    
    # Print elements of both arrays side-by-side
    for ((i=0;i<${#f1[@]};i++)) ; do echo ${f1[i]} ${f2[i]}; done
    

    如果您希望列对齐,或者将echo 更改为printf

    printf "%-20s %-20s\n" ${f1[i]} ${f2[i]}
    

    如果您的文件为 100 兆字节,我不建议您这样做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多