Domanda

In una directory, ho un sacco di file * .html . Vorrei rinominarli tutti in * .txt

Come posso farlo? Uso la shell bash.

È stato utile?

Soluzione

Per una soluzione migliore (con solo funzionalità bash, al contrario delle chiamate esterne), vedi uno delle altre risposte .


Quanto segue farebbe e non richiede che il sistema disponga del programma rinomina (anche se molto spesso lo avresti su un sistema):

for file in *.html; do
    mv "$file" "$(basename "$file" .html).txt"
done

EDIT: Come sottolineato nei commenti, questo non funziona per i nomi di file con spazi al loro interno senza una corretta citazione (ora aggiunta sopra). Quando lavori esclusivamente sui tuoi file che sai di non avere spazi nei nomi dei file, questo funzionerà ma ogni volta che scrivi qualcosa che può essere riutilizzato in un secondo momento, non saltare la citazione corretta.

Altri suggerimenti

Se si utilizza bash, non sono necessari comandi esterni come sed, basename, rename, expr, ecc.

for file in *.html
do
  mv "$file" "${file%.html}.txt"
done
rename 's/\.html$/\.txt/' *.html

fa esattamente quello che vuoi.

Questo ha funzionato per me su OSX da .txt a .txt_bak

find . -name '*.txt' -exec sh -c 'mv "<*>" "${0%.txt}.txt_bak"' {} \;

Desideri utilizzare rinomina :

rename -S .html .txt *.html

Questo fa esattamente quello che vuoi - cambierà l'estensione da .html a .txt per tutti i file corrispondenti a * .html .

Nota: Greg Hewgill sottolinea correttamente che questo non è un built-in bash; ed è un comando Linux separato. Se hai solo bisogno di qualcosa su Linux, questo dovrebbe funzionare bene; se hai bisogno di qualcosa di più multipiattaforma, dai un'occhiata a una delle altre risposte.

Su un Mac ...

  1. Installa rinomina se non hai: brew install rename
  2. rinomina -S .html .txt * .html

Per utenti Ubuntu:

rename 's/\.html$/\.txt/' *.html

Ecco un esempio del comando rename:

rename -n ’s/\.htm$/\.html/’ *.htm

-n significa che è un test eseguito e non cambierà alcun file. Ti mostrerà un elenco di file che verrebbero rinominati se rimossi -n. Nel caso sopra, convertirà tutti i file nella directory corrente da un'estensione di file .htm a .html.

Se l'output dell'esecuzione del test precedente sembrava corretto, è possibile eseguire la versione finale:

rename -v ’s/\.htm$/\.html/’ *.htm

Il -v è facoltativo, ma è una buona idea includerlo perché è l'unico record che avrai delle modifiche che sono state fatte dal comando rename come mostrato nell'output di esempio qui sotto:

$ rename -v 's/\.htm$/\.html/' *.htm
3.htm renamed as 3.html
4.htm renamed as 4.html
5.htm renamed as 5.html

La parte difficile nel mezzo è una sostituzione Perl con espressioni regolari, evidenziata di seguito:

<*>

Dopo la scansione del sito Web di qualcun altro, ho trovato migliaia di file privi dell'estensione .html, in un ampio albero di sottodirectory.

Per rinominarli tutti in un colpo solo, tranne i file che già avevano un'estensione .html (molti di loro non ne avevano affatto), questo ha funzionato per me:

cd wwwroot
find . -xtype f \! -iname *.html   -exec mv -iv "{}"  "{}.html"  \;  # batch rename files to append .html suffix IF MISSING

Nel caso dell'OP potrei modificarlo leggermente, per rinominare solo i file * .txt, in questo modo:

find . -xtype f  -iname *.txt   -exec filename="{}"  mv -iv ${filename%.*}.{txt,html}  \; 

Suddiviso (hammertime!):

-iname * .txt
  - I mezzi considerano SOLO i file che terminano già in .txt

mv -iv " {}. {txt, html} "   - Quando trova passa un {} come nome file, $ {nome file%. *} Estrae il nome base senza alcuna estensione per formare i parametri in mv . bash utilizza {txt, html} per riscriverlo come due parametri, quindi il comando finale viene eseguito come: mv -iv " nomefile.txt " & Quot; filename.html "

Correzione necessaria però: gestione degli spazi nei nomi dei file

Questa domanda menziona esplicitamente Bash, ma se ti capita di avere ZSH disponibile è piuttosto semplice:

zmv '(*).*' '$1.txt'

Se ottieni zsh: comando non trovato: zmv , esegui semplicemente:

autoload -U zmv

E quindi riprovare.

Grazie a questo articolo originale per l'informazione su zmv.

Questa è la soluzione più semplice che ho trovato che funziona su OSX e Linux e funziona anche con git!

trova. -name " *. js " -exec bash -c 'mv " $ 1 " " $ {1% .js} " .tsx '-' {} '\;

e con git:

trova. -name " *. js " -exec bash -c 'git mv " $ 1 " " $ {1% .js} " .tsx '-' {} '\;

Il comando mmv sembra svolgere questo compito in modo molto efficiente su un numero enorme di file (decine di migliaia in un secondo). Ad esempio, per rinominare tutti i file .xml in .html , utilizzare questo:

mmv ";*.xml" "#1#2.html"

il ; corrisponderà al percorso, il * corrisponderà al nome del file e questi saranno denominati # 1 e # 2 nel nome di sostituzione.

Le risposte basate su exec o pipe erano troppo lente o fallivano su un numero molto grande di file.

Prova questo

rename .html .txt *.html 

utilizzo:

rename [find] [replace_with] [criteria]

Un po 'in ritardo alla festa. Potresti farlo con xargs:

ls *.html | xargs -I {} sh -c 'mv $1 `basename $1 .html`.txt' - {}

O se tutti i tuoi file sono in una cartella

ls folder/*.html | xargs -I {} sh -c 'mv $1 folder/`basename $1 .html`.txt' - {}

Se preferisci PERL, c'è un breve script PERL (scritto in origine da Larry Wall, il creatore di PERL) che farà esattamente quello che vuoi qui: tips.webdesign10.com/files/rename.pl.txt . Per il tuo esempio, quanto segue dovrebbe fare il trucco

rename.pl 's / html / txt /' * .html

=)

(Grazie @loretoparisi per l'URL aggiornato)

Sfortunatamente non è banale fare in modo portabile. Probabilmente avrai bisogno di un po 'di magia expr.

for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done

Rimuovi l'eco quando sei felice fa quello che vuoi.

Modifica: basename è probabilmente un po 'più leggibile per questo caso particolare, sebbene expr sia più flessibile in generale.

Questo è un buon modo per modificare più estensioni contemporaneamente:

for fname in *.{mp4,avi}
do
   mv -v "$fname" "${fname%.???}.mkv"
done

Nota: prestare attenzione alla dimensione dell'estensione per essere la stessa (???)

Nice & amp; semplice!

find . -iname *.html  -exec mv {} "$(basename {} .html).text"  \;

Ecco cosa ho usato per rinominare i file .edge in .blade.php

for file in *.edge; do     mv "$file" "$(basename "$file" .edge).blade.php"; done

Funziona come il fascino.

Una riga, nessun loop: ls -1 | xargs -L 1 -I {} bash -c 'mv $ 1 " $ {1%. *}. txt "' _ {}

cbongiorno@ip-172-31-26-242:~/pgsql$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.json  ac8453e2-0d82-4d43-b80e-205edb754700.json
cbongiorno@ip-172-31-26-242:~/pgsql$ ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}
cbongiorno@ip-172-31-26-242:~/pgsql$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.txt  ac8453e2-0d82-4d43-b80e-205edb754700.txt
cbongiorno@ip-172-31-26-242:~/pgsql$ 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top