Bash数组脚本排除重复项

时间:2016-11-02 20:46:56

标签: arrays linux bash

所以我为Raspberry Pi编写了一个bash脚本(名为music.sh)来执行以下功能:

  • 执行时,查看一个目录(音乐文件夹)并选择要查看的随机文件夹。 (注意:这些文件夹中没有一个具有子目录)
  • 在" Music"中的文件夹之后已被选中,然后播放所有mp3文件IN ORDER,直到到达最后一个mp3文件
  • 此时,脚本将返回到" Music"中的文件夹。目录并选择另一个随机文件夹
  • 然后它将再次按顺序播放该文件夹中的所有mp3文件
  • 无限循环直到用户输入

我有这个代码,它完成上述所有EXCEPT以下项目:

  • 我不想播放任何其他的#34;专辑"已经播放过
  • 一旦所有专辑播放一次,然后关闭系统

到目前为止,我的代码正在运行(允许重复):

#!/bin/bash
    folderarray=($(ls -d /home/alphekka/Music/*/))
    for i in "${folderarray[@]}";
    do
    folderitems=(${folderarray[RANDOM % ${#folderarray[@]}]})    
        for j in "${folderitems[@]}";
        do
        echo `ls $j`
        cvlc --play-and-exit "${j[@]}"
        done
   done
exit 0

请注意,单个文件夹或文件中没有名称空格。如果有空格,那么我在使用此代码时会遇到一些问题。

无论如何,我已经接近了,但我并不完全支持我正在寻找的全部功能。任何帮助将不胜感激!非常感谢你! :)

3 个答案:

答案 0 :(得分:3)

使用关联数组作为集合。请注意,这适用于所有有效文件夹和文件名。

#!/bin/bash

declare -A folderarray
# Each folder name is a key mapped to an empty string
for d in /home/alphekka/Music/*/; do
  folderarray["$d"]=
done

while [[ "${!folderarray[*]}" ]]; do
  # Get a list of the remaining folder names
  foldernames=( "${!folderarray[@]}" )
  # Pick a folder at random
  folder=${foldernames[RANDOM%${#foldernames[@]}]}
  # Remove the folder from the set
  # Must use single quotes; see below
  unset folderarray['$folder']
  for j in "$folder"/*; do
    cvlc --play-and-exit "$j"
  done
done

处理包含空格(可能还有其他特殊字符)的键很棘手。上面对unset的调用中显示的引号不是通常意义上的语法引号。它们不会阻止$folder被展开,但它们似乎被unset本身用来引用结果字符串。

答案 1 :(得分:0)

包含mpvrl(随机线),xargsfind的单线性解决方案:

find /home/alphekka/Music/ -maxdepth 1 -type d -print0 | rl -d \0 | xargs -0 -l1 mpv

答案 2 :(得分:0)

这是另一个解决方案:首先随机化目录列表,将结果保存在数组中,然后播放(我的脚本只是打印)来自数组中每个元素的文件

MUSIC=/home/alphekka/Music
OLDIFS=$IFS
IFS=$'\n'
folderarray=($(ls -d $MUSIC/*/|while read line; do echo $RANDOM $line; done| sort -n | cut -f2- -d' '))
for folder in ${folderarray[*]};
do
 printf "Folder: %s\n" $folder
 fileArray=($(find $folder -type f))
 for j in ${fileArray[@]};
 do
  printf "play %s\n" $j
 done
done

对于我使用this answer的随机改组。