如何在Shell脚本中使用2个数组进行for循环?

时间:2018-08-16 17:54:47

标签: bash shell

我必须首先声明两个我也需要帮助的数组。

最初是两个变量。

day=$(hadoop fs -ls -R /user/hive/* | 
        awk '/filename.txt.gz/' |
        tail -1 | 
        date -d $(echo `awk '{print $6}'`) '+%b %-d' | 
        tr -d ' ')

time_stamp=$(hadoop fs -ls -R /user/hive/* | 
             awk '/filename.txt.gz/' |
             tail -1 | 
             awk '{ print $7 }')

现在我需要tail -1而不是tail -5。那么首先,我如何制作这两个数组?

第二个问题,如何使用for$day的配对值中的每个值进行$time_stamp循环?我不能使用array_combine,因为我需要分别对每个数组执行操作。谢谢

1 个答案:

答案 0 :(得分:0)

您正在将数据收集到字符串中,而不是数组中。但此外,您的代码可能应该进行重大重构-作为一般经验法则,如果Awk中发生了某些情况,其余大部分也应在Awk中发生。

您使用variable=(values of array)分配给一个数组,并从子流程中获取值,它是variable=($(command to produce values))

这是重构代码的第一次尝试。

# Avoid repeated code -- break this out into a function
extract_field () {
    hadoop fs -ls -R /user/hive/* | 
    # Get rid of the tail and the repeated Awk
    # Notice backslashes in regex
    # Pass in the field to extract as a parameter
    awk -v field="$1" '/filename\.txt\.gz/ { d[++i]=$field }
        END { for(j=i-5; j<=i; ++j) print d[j] }'
)

day=($(extract_field 6 |
    # Refactor accordingly
    # And if you don't want a space in the format string, don't put a space in the format string in the first place
    xargs -i {} date -d {} '+%b%-d'))

time_stamp=($(extract_field 7))

我对两次调用Hadoop命令的安排表示高度怀疑。也许只需要一次提取字段6和7,然后对结果进行后处理就可以将它们分成两个单独的数组。代替这样的东西吗?

combined=($(hadoop fs -ls -R /user/hive/* | 
    awk '/filename\.txt\.gz/ { d[++i]=$6 " " $7 }
        END { for(j=i-5; j<=i; ++j) print d[j] }'))
for ((i=0; i<"${#combined[@]}"; ++i)); do
    day[$i]="$(date -d "${combined[i]% *}" +'%b%-d')"
    time_stamp[$i]="${combined[i]#* }"
done
unset combined

您需要彼此独立处理日期和时间的声明听起来很可疑;如果您能找到避免这种情况的方法,也许毕竟不要将combined分成两个单独的数组。上面的代码揭示了如何从combined中的值中提取日期和时间(该机制称为parameter substitution)。显然,它还演示了如何遍历数组中的索引。