Talvez não seja uma solução muito inteligente:
- classificar arquivos por nome
- faça um loop pelos nomes
-
compare os caracteres do último loop:
last="" ls -1 $1 | sort | while read file; do sub=${file:0:3} [ "$last" != "$sub" ] && { echo "NEW GROUP"; last="$sub"; } echo "[$sub] $file" done
Em vez de ecoar nomes de arquivos de coleta dentro de uma matriz ...
Apenas uma ideia ... exemplo:
NEW GROUP
[Hi8] Hi8-01-002.avi
NEW GROUP
[VHS] VHS-01-001.avi
[VHS] VHS-01-002.avi
[VHS] VHS-02-002.avi
NEW GROUP
[XZU] XZU
Editar 1: com base na resposta de Anthony Geoghegan , evite os canos no começo do loop e use bash globbing. Dê uma olhada no comentário dele.
script melhorado:
last=""
for file in *avi; do
sub=${file:0:3}
[ "$last" != "$sub" ] && { echo "NEW GROUP"; last="$sub"; }
echo "[$sub] $file"
done
Editar 2:
como solicitado por @ Tony Tan em seu terceiro comentário: aqui você encontra uma solução direta para analisar os nomes dos arquivos coletados em uma função. Existem muitas maneiras de fazer isso. E eu não tenho muita experiência em bash scripting ...;)
#!/bin/bash
SOURCE_DIR="$1"
cd "$SOURCE_DIR" || { echo "could not read dir '$SOURCE_DIR'"; exit 1; }
function parseFiles() {
echo "parsing files:"
echo "$1"
}
last=""
declare -a fileGroup
for file in *avi; do
# first 3 chars of filename
sub=${file:0:3}
if test -z "$last"; then
# last is empty. first loop
last="$sub"
elif test "$last" != "$sub"; then
# new file group detected, parse collected
parseFiles "${fileGroup[*]}"
# reset array
fileGroup=()
last="$sub"
fi
# append name to array
fileGroup[${#fileGroup[@]}]=$file
done
parseFiles "${fileGroup[*]}"