lista arquivos com as mesmas três primeiras letras seguidas por uma sequência # com shell script

0

Primeira vez para postar aqui. Como faço para agrupar arquivos com as mesmas 3 primeiras letras seguidas por um número de seqüência em um diretório? por exemplo,

VHS-01-001.avi
VHS-01-002.avi
-------------
VHS-02-001.avi
VHS-02-002.avi
VHS-02-003.avi
---------
Hi8-01-001.avi
Hi8-01-002.avi
Hi8-01-003.avi

para que eu possa passar cada grupo de arquivos de vídeo em uma função como a seguinte:

encode(){
  for avi in "$@" 
  do..
}
    
por Tony Tan 09.05.2017 / 10:19

2 respostas

3

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[*]}"
    
por 09.05.2017 / 10:35
1

com zsh :

files=(???-??-*.avi)
for prefix (${(Mu)files#???-??-}) encode $prefix*.avi

(ou encode ${(M)files:#$prefix*} )

O equivalente ao shell GNU ( bash ) e ferramentas seria:

while IFS= read -u3 -rd '' prefix; do
  encode "$prefix-"*.avi 3<&-
done 3< <(printf '%s
files=(???-??-*.avi)
for prefix (${(Mu)files#???-??-}) encode $prefix*.avi
' ???-??-*.avi | grep -oz '^...-..-' | sort -zu)

O mesmo princípio. Obtemos a lista de arquivos que correspondem ao padrão ???-??-*.avi no diretório atual, extraia a parte que corresponde a ( (M) / grep -o ) ???-??- (regexp ...-..- ), exclusivas ( (u) / sort -u ) e, em seguida, percorra essa lista de prefixos.

    
por 09.05.2017 / 10:29