【问题标题】:Loop to create files by iterating over array in Bash通过在 Bash 中迭代数组来循环创建文件
【发布时间】:2019-03-19 07:53:24
【问题描述】:

我的 Bash 脚本的逻辑存在错误。我有一个数组,包含数字、大写和小写值,我试图循环并根据数组值创建文件。所有数字文件都被创建,小写文件也是如此,但大写文件不会被创建。

我尝试使用bash +x scriptname.sh 调试脚本,这表明文件已创建,但它们没有出现在目录中。我还做了一个echo "${LETTERNUM[k]}",它表明循环正在迭代正确的次数。

附带问题,有没有更清洁的方法来做到这一点?我觉得${LETTERNUM[k]} 的反复调用可能不是最好的——有没有不同/更好的方法来打印 8 次?而且我确信还有其他方法,例如touch{a..z} 来生成文件,但我需要该数组用于脚本的另一部分。

#!/bin/bash
declare -a LETTERNUM=("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" "1" "2" "3" "4" "5" "6" "7" "8" "9" "0");

for (( k=0; k<=61; k++ ))
do

     > "${LETTERNUM[k]}${LETTERNUM[k]}${LETTERNUM[k]}${LETTERNUM[k]}${LETTERNUM[k]}${LETTERNUM[k]}${LETTERNUM[k]}${LETTERNUM[k]}".txt
done

【问题讨论】:

  • "文件已创建,但没有出现在目录中" 什么意思?
  • 当我在脚本上运行 bash +x 命令时——无论是使用触摸还是 >——它都会显示输出,例如“触摸 MMMMMMMM.txt”。尽管有小写文件和数字文件,但该目录中不存在大写文件。
  • 也许您在使用不区分大小写的文件系统的 Mac 上?
  • 我正在通过 Vagrant 运行 Ubuntu 映像,但我的主机是 MacOS。也许是因为它是一个共享目录?
  • 因为共享目录!我将它从那里移出并重新运行,所以它完全在 Ubuntu 映像上,并且可以正常工作。谢谢@MarkSetchell

标签: arrays bash loops


【解决方案1】:

试试下面的方法,直接遍历数组并使用 touch 命令创建文件:

#!/bin/bash
declare -a LETTERNUM=("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" "1" "2" "3" "4" "5" "6" "7" "8" "9" "0");

for i in "${LETTERNUM[@]}"
do
    touch $i.txt
done

【讨论】:

  • 这绝对更干净(非常感谢!)但我仍然没有得到大写字母,例如 AAAAAAA.txt。
【解决方案2】:

我只是更改了它以使文件名的生成更清晰。关于大写字母,我无法复制错误,因为所有文件都在我的系统上正确生成,包括大写字母。

#!/bin/bash

declare -a LETTERNUM=("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" "1" "2" "3" "4" "5" "6" "7" "8" "9" "0");

for i in "${LETTERNUM[@]}"; do
    touch $(printf "${i}%.0s" {1..8})".txt"
done

【讨论】:

    【解决方案3】:

    如果我试图将所有大写和小写字符和数字 [0-9] 作为索引数组的元素,我只需使用包含所需字符的字符串,循环长度并使用 字符串索引 将每个字符添加到数组中。有一些实用程序可以创建字符序列,但不能保证安装。

    使用 C 风格 for 循环的快速方法是:

    ## string containing all characters
    c=abcdefghijklmnopqrstuvwxyzABCDEFGHINJLMNOPQRSTUVWXYZ0123456789
    
    ## loop over each char
    for ((i = 0; i < ${#c}; i++)); do
        a+=( ${c:i:1} )     ## add each char as array element
    done
    declare -p a   ## output filled array to confirm
    

    您可以复制/鼠标中键粘贴到终端中以查看形成的数组:

    $ c=abcdefghijklmnopqrstuvwxyzABCDEFGHINJLMNOPQRSTUVWXYZ0123456789
    > for ((i = 0; i < ${#c}; i++)); do
    >     a+=( ${c:i:1} )
    > done
    > declare -p a
    declare -a a='([0]="a" [1]="b" [2]="c" [3]="d" [4]="e" [5]="f" [6]="g" [7]="h" 
    [8]="i" [9]="j" [10]="k" [11]="l" [12]="m" [13]="n" [14]="o" [15]="p" 
    [16]="q" [17]="r" [18]="s" [19]="t" [20]="u" [21]="v" [22]="w" [23]="x" 
    [24]="y" [25]="z" [26]="A" [27]="B" [28]="C" [29]="D" [30]="E" [31]="F" 
    [32]="G" [33]="H" [34]="I" [35]="N" [36]="J" [37]="L" [38]="M" [39]="N" 
    [40]="O" [41]="P" [42]="Q" [43]="R" [44]="S" [45]="T" [46]="U" [47]="V" 
    [48]="W" [49]="X" [50]="Y" [51]="Z" [52]="0" [53]="1" [54]="2" [55]="3" 
    [56]="4" [57]="5" [58]="6" [59]="7" [60]="8" [61]="9")'
    

    可能有许多不同的方法,但就效率而言,内置的字符串索引参数扩展可能与 61 个字符一样快。

    【讨论】:

      猜你喜欢
      • 2018-03-01
      • 1970-01-01
      • 2015-09-08
      • 1970-01-01
      • 2015-04-04
      • 1970-01-01
      • 1970-01-01
      • 2013-01-14
      • 2023-02-23
      相关资源
      最近更新 更多