【问题标题】:Loop over an associative array and use the values for another action?循环关联数组并将这些值用于另一个操作?
【发布时间】:2016-02-14 08:58:58
【问题描述】:

第一次写 bash 脚本。我只是从 stackoverflow 问题中找到的零碎示例。

问题:如何将声明为imagetable 的关联数组与调整大小脚本结合起来,以便它根据键值循环操作。

关联数组:

declare -A imagetable
imagetable=(
    ["custom-insights-laptop_1x.png"]   937x508
    ["custom-insights-laptop_2x.png"]   1874x1015
)

调整脚本大小

#!/bin/bash

#replace this -name value from imagetable
RETINA_IMAGES=`find . -name "custom-insights-laptop_1x.png"`

for retina_path in $RETINA_IMAGES
do
  target_path="${retina_path%.png}.png"

  #replace the -resize value from imagetable.
  convert -resize 937x508 $retina_path $target_path 

  echo "Converted ${retina_path} to ${target_path}"
done

【问题讨论】:

  • 我很惊讶你的分配代码甚至可以工作。你真的在使用 bash 吗?因为imagetable 赋值是一个语法错误,在执行它时应该给你“在分配关联数组时必须使用下标”错误。例如,您需要 ["custom-insights-laptop_1x.png"]="937x508" 而不是 ["custom-insights-laptop_1x.png"] "937x508"。我能找到的唯一解释是你并没有真正执行declare -A imagetable,所以你最终得到了一个常规索引数组。
  • 以上所有内容都是正确的,但是如果您减少在代码中发布的“数组”元素的数量,您的问题会更容易解决。我们真的不需要看到整个事情来提供帮助。虽然// 可以作为非工作代码中的注释,但使用标准# char 并避免一整类无法解读的错误消息;-) 并且.. 您嵌入了似乎是问题的 cmets,但它不是真的很清楚你的问题是什么。您希望我们剪切/粘贴您的代码并为您调试吗?
  • 对不起,我来自 javascript :( 我会解决这个问题。
  • @shellter 感谢您的批评,这个问题更有意义吗?
  • 马修:少即是多!我得去遛邻居的狗。希望我能回来看看你的问题;-)。或者你有没有尝试 4ae1e1 的建议,我认为他们是目标

标签: arrays bash loops imagemagick associative-array


【解决方案1】:

我想我理解你的需要,但我不清楚你的RETINA_IMAGES=$(find .. )

这些肯定会对你有所帮助。

declare -A imagetable
imagetable=(
    [custom-insights-laptop_1x.png]=937x508
    [custom-insights-laptop_2x.png]=1874x1015
)

for i in ${!imagetable[*]} ; do
   echo "#dbg: i = $i and \${imagetable[$i]}=${imagetable[$i]}"

   sz=${imagetable[$i]}
   convert -resize "${sz}" "$retina_path" "$target_path"
done

通过 dbl 引用变量的使用来避免一整类 shell 脚本错误,就像我在转换行所做的那样。

如果您需要进一步的帮助,请发表评论。

你可以通过这样做来学习很多关于关联数组的知识

echo ${!arr[*]} 
echo ${arr[*]}
echo ${#arr[*]}
echo ${arr[key]}

编辑

所以更进一步,无需将文件名保存为 RETINA_IMAGES(感谢@MarkSetchell,我现在明白了 ;-)

试试类似的东西

fileTarget="custom-insights-laptop_1x.png"
find . -name "$fileTarget" \
| while read retina_path ; do
  target_path="${retina_path%.png}.png"

  #replace the -resize value from imagetable.
  convert -resize ${imagetable[$fileTarget]} $retina_path $target_path 

  echo "Converted ${retina_path} to ${target_path}"
done 

然后您可以为所有 ${!imagetable[*]} 值创建一个 for 循环,设置 $fileTarget。

IHTH

【讨论】:

  • 是的,这是要走的路——很好的答案。我认为find (正确地)在那里,因为 OP 在多个目录中有同名的图像,他想调整它们的大小。
【解决方案2】:

我认为您只需要一些代码帮助,这似乎最简单,并且您不需要关联数组:

imgfile[0]="fileA.png"
imgfile[1]="fileB.png"
imgfile[2]="fileC.png"

for f in ${imgfile[@]}
do
    IMGSET=$(find . -name "$f")
    #other iterative code here
done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-03
    • 2019-01-30
    • 2011-02-10
    • 1970-01-01
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多