Script o programma Linux per abbreviare i nomi dei file


8

Non ho avuto molto successo nel trovare una versione Linux di namemangler , che ho bisogno di rinominare 1000 di file in modo che siano leggibili su Windows.

Qualcuno sa di un programma Linux che può farlo?

In caso contrario, uno script potrebbe funzionare in quanto ho solo bisogno di rinominare tutti i file in una cartella per, diciamo, i primi 16 caratteri. Ho il sospetto che valga la pena percorrere la route dello script, ma non sono sicuro da dove cominciare.


2
Probabilmente potresti scrivere rapidamente uno script Python o Perl o Ocaml o Ruby.

Perché non puoi semplicemente usare un filesystem vfat, che consente nomi di file lunghi?
wnoise

2
Per curiosità, quanto durano i nomi e cosa contengono che non sono riconosciuti da Windows?
Bobby

Risposte:


10

Su Debian, Ubuntu e derivati, se si accede man renameal prompt dei comandi, si otterrà la pagina del manuale per un'utilità di ridenominazione che consente di utilizzare comandi di espressione regolare simili a Perl nella ridenominazione.

Ad esempio, ciò ridurrà (troncando) tutti i file nella directory corrente a una lunghezza di cinque:

rename 's/^(.{5}).*/$1/' *

Funziona catturando i primi cinque personaggi e poi usando quello nella sostituzione, rimuovendo il resto.

Un altro esempio è quello di abbreviare i nomi dei file (estensione sans) a cinque caratteri, preservando l'estensione:

rename 's/^(.{5}).*(\..*)$/$1$2/' *

Cattura due gruppi, il primo è il primo a cinque caratteri, il secondo è l'estensione. Ciò si trasformerebbe myCarefullyCraftedDocument.pdfin myCar.pdf.

Avvertenza: utilizzalo attentamente, preferibilmente su una copia della tua directory o eseguendo prima i backup. Sei stato avvertito!! Come minimo, usa rename -nprima, che ti mostrerà cosa sarebbe stato fatto senza farlo davvero.


1
questo eliminerà il prefisso come in PDF? e cosa accadrebbe ai file con lo stesso nome una volta abbreviati?

Quel particolare esempio sì, sì. Puoi scrivere una regex per lasciare solo l'estensione. Aggiornerò la risposta. Protegge anche dalla sovrascrittura dei file già esistenti, quindi le ridenominazioni successive non riusciranno.

grazie per il vostro aiuto su questo - Sono molto grato. Ho un piccolo problema se alcuni file PDF verranno rinominati in 5, diciamo cosa succederebbe al PDF che tenta di rinominare con lo stesso nome? È un modo in cui possiamo semplicemente aggiungere un numero univoco a tutti quelli con questo è? vedi sotto ename -n 's / ^ (. {5}). * (\ .. *) $ / $ 1 $ 2 /' * Allegati 123114345234525.pdf rinominati come Annex.pdf Allegati 123114432452352.pdf rinominati come Annex.pdf

@Grimlockz, non penso che tu possa mettere quel tipo di intelligenza nella regex di rinomina stessa. Ciò che potrebbe essere necessario fare è scrivere uno script per racchiudere il nome con quel tipo di intelligenza, ed è meglio che venga posta come una domanda separata in modo da far rispondere più persone che solo io.

@Grimlockz Ecco perché non vuoi fare tutto in una regex. Sarai più felice e meglio scrivere una sceneggiatura che usa regex.
Spencer Rathbun,

3

È possibile spostare i file in conflitto in un'altra directory:

for i in *
do
    j=${i:0:16}

    if [ -e "$j" ]
    then
        mv "$i" /path/to/rename/later
    else
        mv "$i" "$j"
    fi
done

1

Puoi scrivere uno script per abbreviare i nomi dei file e rimuovere i caratteri che Windows non gradisce in poche righe di bash. Avviso, codice non testato, digitato direttamente nel mio browser.

shopt -s dotglob extglob
for x in *; do
  y=${x//+([!-!#$%&'().0-9@A-Z^_`a-z{}~])/_}  # change all problematic characters to _
  if [[ $y = .* ]]; then y=_${y#.}; fi        # change dot files to begin with _
  y=${y:0:16}                                 # truncate names
  y=${y,,}                                    # convert to lowercase
  if [[ -e $y || $y =~ ^(aux|clock\$|com[0-9]|con|lpt[0-9]|nul|prn)(\.*)?$ ]]; then
    # The file exists or is a DOS/Windows reserved name.
    # Change foo.bar to foo~1.bar, foo~2.bar, ... (I ignore the length restriction here)
    i=1
    if [[ $y =~ \. ]]; then
      prefix=${y%%.*}; suffix=.${y#*.}
    else
      prefix=$y; suffix=
    fi
    y=${prefix}~$i$suffix
    while [[ -e $y ]]; do
      ((++i))
      y=${prefix}~$i$suffix
    done
  fi
  mv -- "$x" "$y"
done

Se è necessario ricorrere in sottodirectory, chiamare uno script di shell da find -depth -exec …. Oppure usa zsh invece di bash; in zsh, si **/*(od)espande a tutti i file nella directory corrente, ricorsivamente, con prima i file più nidificati.


1

Lo scripting Shell / python / perl per questo tipo di cose va bene, ma sembra che un'app gui sia la migliore per te, quindi consiglierei pyRenamer , che può fare esattamente quello che vuoi, tra le altre cose (semplici operazioni comuni tramite preset [eliminazione di spazi, troncamento del nome file da un punto all'altro], ricerca / sostituzione semplice, regex complicato, anteprima, ecc.).

La tua distribuzione potrebbe anche averlo nel loro repository di software (Fedora sì).


0

Alcuni sistemi non hanno il renamecomando, quindi in alternativa alla risposta di paxdiablo, ecco come fare la stessa cosa mv.

for f in *.pdf; do 
    tmp=`echo $f | sed -r 's//^(.{5}).*(\..*)$/$1$2/'`
    mv -b ./"$f" ./"$tmp"
done

Il -bflag in movimento crea un backup dei file che verrebbero eliminati o sovrascritti. Modificando il modello glob nel ciclo for è possibile regolare i file su cui viene eseguito, usando *da solo per essere eseguito su tutti i file.


1
Non c'è bisogno di usare echoe una pipe (potrebbe essere molto costosa se hai molti file), usa invece un heredoc o herestring.
Chris Down,

1
@ChrisDown vedi qui . Secondo l'articolo wiki , i processi con piping sono biforcati, ma non dice nulla sull'eseguirli nelle proprie shell.
Spencer Rathbun,

1
Ad esempio, notare la differenza tra eval 'echo $BASH_SUBSHELL'e eval 'echo $BASH_SUBSHELL' | cat.
Chris Down,

2
Ho appena fatto un test rapido, ho timeusato un loop usando echo $i | sede un altro usando sed ... <<<$i, e l'herestring ha impiegato circa 2/3 del tempo dell'eco.
Kevin,

1
@SpencerRathbun Sì. <<inizia un <i> doc </i> qui, che è multilinea e richiede delimitatori. <<<crea una <i> stringa </i> qui, che accetta solo una variabile / stringa. Provalo, var=abc // cat<<<$var // cat <<$var.
Kevin,

0

Se hai bisogno di provare a rinominare i file e ti capita di avere librerie KDE installate sul tuo sistema (o non ti dispiace aggiungerle), controlla krename.

Ti consente di svolgere alcune semplici attività di ridenominazione direttamente con i suoi strumenti e consente anche espressioni regolari per situazioni più complicate.

Ti mostra un'anteprima dei file rinominati mentre crei le condizioni di ridenominazione. Ti consente anche di rinominare nuovamente gli stessi file, il che è utile se vuoi fare qualcosa di complicato in cui farlo in fasi ridurrebbe la complessità di ogni fase a qualcosa che puoi capire rapidamente.


-1
for file in *; do
    mv "$file" $(echo "$file" | sed -e 's/[^A-Za-z0-9._-]/_/g')
done &
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.