首页 > 解决方案 > bash 中的多个列表和多个文件类型

问题描述

问题

存在对不同文件执行一系列操作的数据处理问题。但是,在处理过程中,不同类别的文件需要专门化。处理步骤冗长而繁琐,目标是创建和维护单个循环。我的尝试试图组成一个子列表的主列表,该列表与列表中元素的特定操作有关。

示意图示例

下面是问题的最小版本。文件类可以用后缀来标记。

代表性输入数据

export suffix=".png .svg"
export foo="a b c"
export bar="alpha beta chi"

期望的行动

在伪代码中

loop over master list
    first sublist foo
        create file names: a.png b.png c.png
    second sublist bar
        create file names: alpha.svg beta.svg chi.svg

额外学分

嵌套计数器会很棒,因为列表很长。例如chi.svg将是步骤 2.3

标签: bashlistnested-loopsnested-lists

解决方案


使用 namerefeval或间接来模拟嵌套数组。

  1. 名称参考:
foo=(a b c)
bar=(alpha beta chi)

arrays=(foo bar)
suffix=(.png .svg)

declare -n arr
let i=0
for arr in "${arrays[@]}"; do
    for elem in "${arr[@]}"; do
        echo "${elem}${suffix[i]}" 
    done
    let i++
done

这声明arr为 nameref。当你操作时arr,你实际上是在操作由 的值指定的变量arr

let j=0您可以使用and为内部循环添加一个计数器let j++,或者执行以下操作:

for (( i = 0; i < ${#arrays[@]}; i++ )); do
    declare -n arr="${arrays[i]}"
    for (( j = 0; j < ${#arr[@]}; j++ )); do
        echo "${arr[j]}${suffix[i]}"
    done
done
  1. eval
foo=(a b c)
bar=(alpha beta chi)

suffix=(.png .svg)
arrays=(foo bar)

for (( i = 0; i < ${#arrays[@]}; i++ )); do
    eval "arr=( \${${arrays[i]}[@]} )"
    for (( j = 0; j < ${#arr[@]}; j++ )); do
        echo "${arr[j]}${suffix[i]}"
    done
done

这将评估 string ,它创建一个包含 的元素的arr=( \${foo[@]} )数组。arrfoo

  1. 间接:
foo=(a b c)
bar=(alpha beta gama)

arrays=('foo[@]' 'bar[@]')
suffix=(.png .svg)

let i=0
for arr in "${arrays[@]}"; do
    for elem in "${!arr}"; do
        echo ${elem}${suffix[i]}
    done
    let i++
done

"${!arr}"指的是数组or foobar但我们无法索引它或获取它的长度(或者我错过了什么?)。因此我们不能for (( j = 0; ... ))在这里使用。

在Bash 参考手册中搜索namerefeval和间接的相关文档。


推荐阅读