Ho intenzione di suggerire tre alternative. Ognuno è un semplice comando a riga singola, ma fornirò varianti per casi più complicati, principalmente nel caso in cui i file da elaborare vengano mescolati con altri file nella stessa direttrice.
mmv
Userei il comando di MMV
dal pacchetto con lo stesso nome :
mmv '*HBO_DPM*' '#1dpm#2'
Si noti che gli argomenti vengono passati come stringhe, quindi l'espansione glob non avviene nella shell. Il comando riceve esattamente due argomenti, quindi trova i file corrispondenti internamente, senza limiti stretti sul numero di file. Si noti inoltre che il comando sopra presuppone che tutti i file che corrispondono al primo glob devono essere rinominati. Naturalmente sei libero di essere più specifico:
mmv 'sb_606_HBO_DPM_*' 'sb_606_dpm_#1'
Se hai file al di fuori dell'intervallo di numeri richiesto nella stessa directory, potresti essere meglio con il ciclo sui numeri indicati più in basso in questa risposta. Tuttavia, è possibile utilizzare anche una sequenza di invocazioni mmv con schemi adeguati:
mmv 'sb_606_HBO_DPM_0089*' 'sb_606_dpm_0089#1' # 0089000-0089999
mmv 'sb_606_HBO_DPM_009*' 'sb_606_dpm_009#1' # 0090000-0099999
mmv 'sb_606_HBO_DPM_01[0-5]*' 'sb_606_dpm_01#1#2' # 0100000-0159999
mmv 'sb_606_HBO_DPM_016[0-2]*' 'sb_606_dpm_016#1#2' # 0160000-0162999
mmv 'sb_606_HBO_DPM_01630[01]?' 'sb_606_dpm_01630#1#2' # 0163000-0163019
mmv 'sb_606_HBO_DPM_016302[0-2]' 'sb_606_dpm_016302#1' # 0163020-0163022
scorrere i numeri
Se vuoi evitare di installare qualcosa o devi selezionare per intervallo di numeri evitando corrispondenze al di fuori di questo intervallo e sei pronto ad aspettare 74,023 invocazioni di comandi, puoi usare un semplice ciclo bash:
for i in {0089000..0163022}; do mv sb_606_HBO_DPM_$i sb_606_dpm_$i; done
Questo funziona particolarmente bene qui poiché non ci sono lacune nella sequenza. Altrimenti potresti voler verificare se il file sorgente esiste realmente.
for i in {0089000..0163022}; do
test -e sb_606_HBO_DPM_$i && mv sb_606_HBO_DPM_$i sb_606_dpm_$i
done
Si noti che in contrasto con for ((i=89000; i<=163022; ++i))
l'espansione del controvento gestisce gli zeri iniziali da quando alcuni Bash rilasciano un paio di anni fa. In realtà una modifica che ho richiesto, quindi sono felice di vedere casi d'uso per questo.
Ulteriori letture: Brace Expansion nelle pagine informative di Bash, in particolare la parte su {x..y[..incr]}
.
loop su file
Un'altra opzione sarebbe quella di eseguire il loop su un glob adatto, anziché semplicemente il loop sull'intero intervallo in questione. Qualcosa come questo:
for i in *HBO_DPM*; do mv "$i" "${i/HBO_DPM/dpm}"; done
Anche questa è una mv
chiamata per file. E ancora il ciclo è su un lungo elenco di elementi, ma l'intero elenco non viene passato come argomento a un sottoprocesso, ma gestito internamente da bash, quindi il limite non ti causerà problemi.
Ulteriori letture: Espansione dei parametri della shell nelle pagine informative di Bash, che documentano ${parameter/pattern/string}
tra l'altro.
Se si desidera limitare l'intervallo di numeri a quello fornito, è possibile aggiungere un controllo per questo:
for i in sb_606_HBO_DPM_+([0-9]); do
if [[ "${i##*_*(0)}" -ge 89000 ]] && [[ "${i##*_*(0)}" -le 163022 ]]; then
mv "$i" "${i/HBO_DPM/dpm}"
fi
done
Qui ${i##pattern}
rimuove la corrispondenza del prefisso più lungo pattern
da $i
. Quel prefisso più lungo viene definito come qualsiasi cosa, quindi un carattere di sottolineatura, quindi zero o più zeri. Quest'ultimo è scritto come *(0)
un modello glob esteso che dipende extglob
dall'opzione impostata. La rimozione degli zeri iniziali è importante per trattare il numero come base 10 e non base 8. L' +([0-9])
argomento nel ciclo è un altro glob esteso, corrispondente a una o più cifre, nel caso in cui ci siano file che iniziano lo stesso ma non finiscono in un numero.
ARG_MAX
limite della shell . Poiché questa domanda richiede esplicitamente una soluzione da riga di comando, anche le soluzioni GUI (possibilmente uguali) come nell'altra domanda non corrispondono.