Come rinominare tutti i file con caratteri e spazi speciali in una directory?


10

Come posso rinominare tutti i file in una directory specifica in cui i file contengono spazi vuoti e caratteri speciali ($ e @) nei loro nomi?

Ho provato il renamecomando come segue per sostituire tutti gli spazi e i caratteri speciali con un _:

$ ls -lrt
total 464
-rwxr-xr-x. 1 pmautoamtion pmautoamtion 471106 Jul 17 13:14 Bharti Blocked TRX Report Morning$AP@20150716.csv


$ rename -n 's/ |\$|@/_/g' *
$ ls -lrt
total 464
-rwxr-xr-x. 1 pmautoamtion pmautoamtion 471106 Jul 17 13:14 Bharti Blocked TRX Report Morning$AP@20150716.csv
$

Il comando funziona ma non apporterà alcuna modifica ai nomi dei file e non restituirà alcun errore. Come posso risolvere questo problema e ci sono anche altri modi?


1
Potresti aspettarti lo script per rinominare il perl (ref: manpages.ubuntu.com/manpages/dapper/man1/prename.1.html ) ma stai invece ottenendo la ridenominazione util-linux, che non funziona allo stesso modo.
Jeff Schaller

Risposte:


10

La -nbandiera è per

--no-act

Nessuna azione: mostra quali file sarebbero stati rinominati.

Quindi è normale se non si apportano modifiche.

Per quanto riguarda il tuo comando, funziona per me:

$ touch "a @ test"
$ ls
a @ test
$ rename -n 's/ |\$|@/_/g' *
a @ test renamed as a___test

Forse a seconda del tuo guscio, devi sfuggire al |

$ rename -n 's/ \|\$\|@/_/g' *

Oppure puoi usare la […]notazione per raggruppare i personaggi:

$ rename -n 's/[ @\$]/_/g' *

1
Ho provato tutti e tre senza l'opzione -n ​​e comunque non cambierà il nome del file. Non do alcun errore per nessuno dei 3 tipi sopra menzionati. Forse il comando rename non funziona per qualche motivo. C'è un altro modo per cambiare tutti i file in una directory con spazi o $ o @ nei loro nomi?
Ankit Vashistha,

@AnkitVashistha rename -n 's/./_/g' *genera qualcosa?
Fredtantini,

Non dà nulla, nessun output, nessun errore. Arriva sulla riga di comando successiva.
Ankit Vashistha,

rinominare inoltre non funziona per me per sostituire (spazio) o ':' su Ubuntu 18.04, Bash 4.4.20 (1) -release
Ouss

7

Potresti provare così:

for file in ./*Block*                                       
do echo mv "$file" "${file//[ ()@$]/_}"
done

Se sei soddisfatto del risultato, rimuovi il echoprecedente mvper rinominare effettivamente i file.


Una delle migliori soluzioni che ho attraversato, ci stavo provando da così tanto tempo
Sushin Pv,

2

alla ricerca di una bella sceneggiatura per rimuovere caratteri speciali e caratteri speciali tedeschi, sostituendoli con quelli universali per non rimuovere informazioni utili Ho aggiornato l'ultima versione della sceneggiatura che ha avuto alcuni problemi minori che hanno comportato:

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfileNOSPECIALS=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  outfileNOoe=`echo $outfileNOSPECIALS| sed -e 's|ö|oe|g'`
  outfileNOae=`echo $outfileNOoe| sed -e 's|ä|ae|g'`
  outfileNOue=`echo $outfileNOae| sed -e 's|ü|ue|g'`
  outfileNOOE=`echo $outfileNOue| sed -e 's|Ö|OE|g'`
  outfileNOAE=`echo $outfileNOOE| sed -e 's|Ä|AE|g'`
  outfileNOUE=`echo $outfileNOAE| sed -e 's|Ü|UE|g'`
  outfileNOss=`echo $outfileNOUE| sed -e 's|ß|ss|g'`
  outfile=${outfileNOss}
  if [ "$infile" != "${outfile}" ]
  then
        echo "filename changed for " $infile " in " $outfile
        mv "$infile" ${outfile}
  fi
done

exit

con il risultato di:

inserisci qui la descrizione dell'immagine

@don_crissti: Sta facendo l'hokus-pokus con il file infile poiché Linux avrebbe i suoi problemi con la gestione di caratteri speciali quando si sposta il nome file.


1
personaggi speciali ? quale ?
don_crissti,

Spazio, a simbolo, e commerciale ....
Matthias R. Wiora,

Non c'è alcun problema a spostare un file con un nome che contiene caratteri speciali (inclusa una nuova riga) ... Probabilmente non hai familiarità con le shell (e a proposito, questo non ha nulla a che fare con Linux, è una funzione shell ... )
don_crissti,

mh okay - forse hai ragione
Matthias R. Wiora il

1

Poiché il renamecomando non ha funzionato per me per motivi sconosciuti e non ho altre risposte per la mia domanda, io stesso ho cercato di fare uno sforzo per rendere possibile la ridenominazione. Questo potrebbe non essere l'approccio migliore per rinominare i file, ma ha funzionato per me ed è per questo che vorrei pubblicarlo come una risposta in modo che se qualcun altro legge questo potrebbe ottenere un aiuto per cambiare i nomi dei file come ho fatto io.

Ora per me, so che tutti i file avranno un testo specifico nei loro nomi che è la parola "Blocco". Di seguito sono riportati i nomi dei file prima che la ridenominazione fosse eseguita:

anks@anks:~/anks$ ls -lrt
total 4
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$AP@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$HP@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$CH@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$KK@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:48 Bharti TRX Block Report$UW@12Jul15.csv

Ora ho scritto un piccolo script di shell per renderlo possibile. Di seguito è riportato il codice:

#!/bin/bash

PATH="/home/ebfijjk/anks"

# Put the old filenames in a file.
ls $PATH | grep Block >> oldValues

# Put the new names without " " or "@" or "$" in another file
cat oldValues | sed 's/\$/_/g' | sed 's/\@/_/g' | sed 's/ /_/g' >> newValues

# Create a new file with Old names and New names seperated by a #.
paste -d'#' oldValues newValues >> oldAndNew

# Read the file with both old and new names and rename them with the new names.
while IFS='#'; read oldValue newValue
do
    mv "$oldValue" "$newValue"

done < oldAndNew

rm oldValues newValues oldandNew

Ed è tutto, quando eseguo lo script, rinomina tutti i nomi dei file con spazi vuoti ( ) $o @con _invece di questi caratteri.


puoi sostituirlo cat foo | sed S1 | sed S2 | sed S3 >> barconsed -e S1 -e S2 -e S3 foo >> bar
Archemar il

2
@Archemar - o semplicemente sed 's/[ ()@$]/_/g'osed 'y/ ()@$/_____/'
don_crissti

Grazie don_crissti e Archemar per i tuoi commenti e suggerimenti.
Ankit Vashistha,

1

Questo solo toglie i caratteri speciali dai nomi dei file

for file in *; do mv "$file" `echo $file | tr -cd '.A-Za-z0-9_-'` ; done
Námásté Egész-ség.mkv --> NmstEgsz-sg.mkv

metti echodopo ; doper testare prima, come:

for file in *; do echo mv "$file" `echo $file | tr -cd '.A-Za-z0-9_-'` ; done

Un'altra soluzione:

rename -v 's/[^a-zA-Z0-9\.\s_-]//g' *.* && rename -v 's/[\s]/_/g' *.*
Námásté Egész-ség.mkv --> Nmst_Egsz-sg.mkv

-n opzione da testare prima.


0

Da tempo cerco una soluzione a questo problema. Lavoro su vecchi sistemi chiusi che non possono avere nuovi pacchetti installati. Non ho il renamecomando. Alla fine ho scritto una sceneggiatura che sembra funzionare con tutti i caratteri speciali immessi sulla tastiera. ~@#$%^&*()-_=+[]{}\|;:",<.>?' Lo script rinominerà ogni file e directory nella directory corrente. Sostituirà tutti i caratteri speciali, tranne -_.il _personaggio. La outfile=linea può essere modificato per utilizzare un carattere diverso per la sostituzione se desiderato. Sostituisci |_|con |.|per usare il .personaggio per esempio.

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfile=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  mv "$infile" ${outfile} &
done

exit

0

Per me su Ubuntu 18.04 LTS con bash 4.4.20 (1), questo one-liner ha funzionato bene per rimuovere gli spazi, @,: # ...

Per testare (notare il echocomando:

for file in ./* ; do if [[ $file == *['!'\ :@#]* ]]; then echo mv "$file" "${file//[ #()@$:]/_}"; fi; done

Eseguire:

for file in ./* ; do if [[ $file == *['!'\ :@#]* ]]; then echo mv "$file" "${file//[ #()@$:]/_}"; fi; 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.