【问题标题】:Retrieve index of array element matching string in Bash在 Bash 中检索匹配字符串的数组元素的索引
【发布时间】:2013-11-15 02:17:17
【问题描述】:

我有钢琴键盘上 88 个琴键的声音文件。

p-book:OUT pi$ ls
Piano.ff.A0.aiff    Piano.ff.Bb7.aiff   Piano.ff.Eb1.aiff
Piano.ff.A1.aiff    Piano.ff.C1.aiff    Piano.ff.Eb2.aiff
Piano.ff.A2.aiff    Piano.ff.C2.aiff    Piano.ff.Eb3.aiff
Piano.ff.A3.aiff    Piano.ff.C3.aiff    Piano.ff.Eb4.aiff
Piano.ff.A4.aiff    Piano.ff.C4.aiff    Piano.ff.Eb5.aiff
Piano.ff.A5.aiff    Piano.ff.C5.aiff    Piano.ff.Eb6.aiff
Piano.ff.A6.aiff    Piano.ff.C6.aiff    Piano.ff.Eb7.aiff
Piano.ff.A7.aiff    Piano.ff.C7.aiff    Piano.ff.F1.aiff
Piano.ff.Ab1.aiff   Piano.ff.C8.aiff    Piano.ff.F2.aiff
Piano.ff.Ab2.aiff   Piano.ff.D1.aiff    Piano.ff.F3.aiff
Piano.ff.Ab3.aiff   Piano.ff.D2.aiff    Piano.ff.F4.aiff
Piano.ff.Ab4.aiff   Piano.ff.D3.aiff    Piano.ff.F5.aiff
Piano.ff.Ab5.aiff   Piano.ff.D4.aiff    Piano.ff.F6.aiff
Piano.ff.Ab6.aiff   Piano.ff.D5.aiff    Piano.ff.F7.aiff
Piano.ff.Ab7.aiff   Piano.ff.D6.aiff    Piano.ff.G1.aiff
Piano.ff.B0.aiff    Piano.ff.D7.aiff    Piano.ff.G2.aiff
Piano.ff.B1.aiff    Piano.ff.Db1.aiff   Piano.ff.G3.aiff
Piano.ff.B2.aiff    Piano.ff.Db2.aiff   Piano.ff.G4.aiff
Piano.ff.B3.aiff    Piano.ff.Db3.aiff   Piano.ff.G5.aiff
Piano.ff.B4.aiff    Piano.ff.Db4.aiff   Piano.ff.G6.aiff
Piano.ff.B5.aiff    Piano.ff.Db5.aiff   Piano.ff.G7.aiff
Piano.ff.B6.aiff    Piano.ff.Db6.aiff   Piano.ff.Gb1.aiff
Piano.ff.B7.aiff    Piano.ff.Db7.aiff   Piano.ff.Gb2.aiff
Piano.ff.Bb0.aiff   Piano.ff.E1.aiff    Piano.ff.Gb3.aiff
Piano.ff.Bb1.aiff   Piano.ff.E2.aiff    Piano.ff.Gb4.aiff
Piano.ff.Bb2.aiff   Piano.ff.E3.aiff    Piano.ff.Gb5.aiff
Piano.ff.Bb3.aiff   Piano.ff.E4.aiff    Piano.ff.Gb6.aiff
Piano.ff.Bb4.aiff   Piano.ff.E5.aiff    Piano.ff.Gb7.aiff
Piano.ff.Bb5.aiff   Piano.ff.E6.aiff
Piano.ff.Bb6.aiff   Piano.ff.E7.aiff

我希望将它们重命名为它们的 MIDI 音符编号:

Piano.ff.A0.aiff  -> 21.aiff
Piano.ff.Bb0.aiff -> 22.aiff
Piano.ff.B0.aiff  -> 23.aiff
Piano.ff.C1.aiff  -> 24.aiff
:

(21 是钢琴上最低音符的 MIDI 编号)

虽然 88 可能更像是“手工”大小,但我很好奇它是否可以在几行 Bash 中自动完成

如果:

'C'  ~ 0  
'Db' ~ 1  
'D'  ~ 2  
:  
'B'  ~ 11  

那么我可以这样做:

MidiNote = NumberForPitchclass( pitchclassstring ) + 12 * octave

但是 Bash 有执行此操作的设备吗?

【问题讨论】:

    标签: arrays string bash split


    【解决方案1】:

    如果您有 bash 4,则可以使用关联数组:

       noteNames=(C Db D Eb E F Gb G Ab A Bb B)
       declare -A noteNumbers
       for (( i=0; i<${#noteNames[@]}; ++i )); do
          noteNumbers[${noteNames[i]}]=$i
       done
       for f in *.aiff; do
          note="${f#Piano.ff.}"
          note="${note%.aiff}"
          name="${note%%[0-9]*}"
          octave="${note#$name}"
          if [ ! -n "${noteNumbers[$name]}" ]; then
             echo >&2 "$0: not renaming $f - note not found"
          else
             let midiNote=${noteNumbers[$name]}+12*octave
             mv "$f" "$midiNote.aiff"
          fi
       done
    

    如果您没有 bash 4,则可以通过循环遍历每个文件的注释而不是在开头只循环一次来手动完成:

    noteNames=(C Db D Eb E F Gb G Ab A Bb B)
    for f in *.aiff; do
       note="${f#Piano.ff.}"
       note="${note%.aiff}"
       name="${note%%[0-9]*}"
       octave="${note#$name}"
       for (( base=0; base<${#noteNames[@]}; ++base )); do
          if [[ "${noteNames[base]}" == $name ]]; then
             break
          fi
       done
       if (( base >= ${#noteNames[@]} )); then
          echo >&2 "$0: not renaming $f - note not found"
       else
          let midiNote=base+12*octave
          mv "$f" "$midiNote.aiff"
       fi
    done
    

    但是,这给 A0 提供了数字 10,而您说它是 21,因此您显然需要在这些数字上加上 11。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-29
      • 1970-01-01
      • 2011-12-03
      相关资源
      最近更新 更多