Wie benenne ich alle Dateien mit Sonderzeichen und Leerzeichen in einem Verzeichnis um?

10

Wie kann ich alle Dateien in einem bestimmten Verzeichnis umbenennen, in dem die Dateien Leerzeichen und Sonderzeichen ($ und @) enthalten?

Ich habe den folgenden renameBefehl versucht , um alle Leerzeichen und Sonderzeichen durch ein _ zu ersetzen:

$ 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
$

Der Befehl funktioniert, nimmt jedoch keine Änderungen an den Dateinamen vor und gibt auch keinen Fehler zurück. Wie kann dies behoben werden und gibt es auch andere Möglichkeiten?

Ankit Vashistha
quelle
1
Möglicherweise erwarten Sie das Perl-Umbenennungsskript (ref: manpages.ubuntu.com/manpages/dapper/man1/prename.1.html ), erhalten jedoch stattdessen eine Util-Linux-Umbenennung, die nicht auf die gleiche Weise funktioniert.
Jeff Schaller

Antworten:

10

Die -nFlagge ist für

--keine Handlung

Keine Aktion: Zeigen Sie an, welche Dateien umbenannt worden wären.

Es ist also normal, wenn Sie keine Änderungen haben.

In Bezug auf Ihren Befehl funktioniert es für mich:

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

Abhängig von Ihrer Shell müssen Sie möglicherweise dem | entkommen

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

Oder Sie können die […]Notation verwenden, um Zeichen zu gruppieren:

$ rename -n 's/[ @\$]/_/g' *
Fredtantini
quelle
1
Ich habe alle drei ohne die Option -n ausprobiert und trotzdem wird der Name der Datei nicht geändert. Ich gebe keinen Fehler für einen der 3 oben genannten Typen. Möglicherweise funktioniert der Befehl zum Umbenennen aus irgendeinem Grund nicht. Gibt es eine andere Möglichkeit, alle Dateien in einem Verzeichnis mit Leerzeichen oder $ oder @ im Namen zu ändern?
Ankit Vashistha
@AnkitVashistha rename -n 's/./_/g' *gibt etwas aus?
Fredtantini
Es gibt nichts, keine Ausgabe, keinen Fehler. Es landet einfach in der nächsten Befehlszeile.
Ankit Vashistha
Umbenennen funktioniert auch nicht für mich, um (Leerzeichen) oder ':' unter Ubuntu 18.04, Bash 4.4.20 (1) -Veröffentlichung
Ouss
7

Sie könnten es so versuchen:

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

Wenn Sie mit dem Ergebnis zufrieden sind, entfernen Sie das echoVorher mv, um die Dateien tatsächlich umzubenennen.

don_crissti
quelle
Eine der besten Lösungen, die ich je durchgemacht habe, ich habe es so lange versucht
Sushin Pv
2

Auf der Suche nach einem ansehnlichen Skript zum Entfernen von Sonderzeichen sowie deutschen Sonderzeichen, das durch universelle Zeichen ersetzt wird, um nützliche Informationen nicht zu entfernen. Ich habe die letzte Version des Skripts aktualisiert, bei der einige kleinere Probleme aufgetreten sind:

#!/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

ergebend:

Geben Sie hier die Bildbeschreibung ein

@don_crissti: Er macht das Hokus-Pokus mit der Infile, da Linux seine eigenen Probleme mit der Behandlung von Sonderzeichen beim Verschieben des Dateinamens haben würde.

Matthias R. Wiora
quelle
1
spezielle Charaktere ? welche ?
don_crissti
Raum, am Symbol, kaufmännisches Und ....
Matthias R. Wiora
Es ist kein Problem , eine Datei mit einem Namen zu verschieben, der Sonderzeichen enthält (einschließlich eines Zeilenumbruchs) ... Sie sind wahrscheinlich nicht mit den Shells vertraut (und übrigens hat dies nichts mit Linux zu tun, es ist eine Shell-Funktion ... )
don_crissti
mh okay - du hast vielleicht recht
Matthias R. Wiora
1

Da der renameBefehl aus unbekannten Gründen bei mir nicht funktioniert hat und ich keine anderen Antworten auf meine Frage bekomme, habe ich mich selbst bemüht, die Umbenennung zu ermöglichen. Dies ist möglicherweise nicht der beste Ansatz, um die Dateien umzubenennen, aber es hat bei mir funktioniert. Deshalb möchte ich es als Antwort veröffentlichen, damit jemand, der dies liest, Hilfe erhält, um die Dateinamen so zu ändern, wie ich es getan habe.

Jetzt weiß ich, dass alle Dateien einen bestimmten Text in ihren Namen haben, nämlich das Wort "Block". Im Folgenden sind die Dateinamen aufgeführt, bevor sie umbenannt wurden:

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

Jetzt habe ich ein kleines Shell-Skript geschrieben, um dies zu ermöglichen. Es folgt der Code:

#!/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

Und das war's, wenn ich das Skript ausführe, benennt es alle Dateinamen mit Leerzeichen ( ) oder $oder @mit _anstelle dieser Zeichen um.

Ankit Vashistha
quelle
Sie können ersetzen cat foo | sed S1 | sed S2 | sed S3 >> bardurchsed -e S1 -e S2 -e S3 foo >> bar
Archemar
2
@Archemar - oder einfach sed 's/[ ()@$]/_/g'odersed 'y/ ()@$/_____/'
don_crissti
Vielen Dank an don_crissti und Archemar für Ihre Kommentare und Vorschläge.
Ankit Vashistha
1

In diesem Fall werden nur die Sonderzeichen aus den Dateinamen entfernt

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

setzen Sie echonach ; do, um vorher zu testen, wie:

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

Eine andere Lösung:

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 Option zum Testen vor.

eapo
quelle
0

Ich habe schon seit einiger Zeit nach einer Lösung für dieses Problem gesucht. Ich arbeite an alten geschlossenen Systemen, auf denen keine neuen Pakete installiert werden können. Ich habe den renameBefehl nicht. Schließlich habe ich ein Skript geschrieben, das anscheinend mit allen über die Tastatur eingegebenen Sonderzeichen funktioniert. ~@#$%^&*()-_=+[]{}\|;:",<.>?' Das Skript benennt jede Datei und jedes Verzeichnis im aktuellen Verzeichnis um. Es werden alle Sonderzeichen außer -_.durch das _Zeichen ersetzt. Die outfile=Zeile kann geändert werden, um bei Bedarf ein anderes Zeichen zum Ersetzen zu verwenden. Ersetzen Sie |_|durch |.|, um beispielsweise das .Zeichen zu verwenden.

#!/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
ScriptKitty37
quelle
0

Für mich unter Ubuntu 18.04 LTS mit Bash 4.4.20 (1) -Veröffentlichung hat dieser Einzeiler gut funktioniert, um Leerzeichen zu entfernen, @ ,: # ...

Zum Testen (beachten Sie den echoBefehl:

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

Ausführen:

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