• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst]Dateien umbenennen mit einer unschärfe!

compi

Member
Ich habe eine Text Datei in der Namen untereinander stehen.

Und einen Ordner mit Dateinamen die in etwa dem entsprechen was in der Datei steht.

Nun würde ich gerne die Dateinamen mit denen in der Textdatei abgleichen oder andersherum.


Die Textdatei ist dabei immer Namensgeber der Dateien.

Was die Unschärfe betrifft:

Unterschiede in der groß und klein Schreibweise, Leerzeichen können Bindestrich oder Underline sein.

z.B.

Textdatei

bla1 Bla1
bLa2_bLa2
bla3-Bla3

Dateinamen:

Bla1 Bla1
bla2 Bla2
Bla3 bla3

raus kommen sollen die Dateinamen:

Bla1 Bla1 -> bla1 Bla1
bla2 Bla2 -> bLa2_bLa2
Bla3 bla3 -> bla3-Bla3
 

abgdf

Guru
Python 2.x, Datendatei muß "data.txt" heißen, das Skript "script.py". Datendatei und Skript sind im Verzeichnis mit den Dateien:
Code:
#!/usr/bin/env python
# coding: iso-8859-1

import os

datafilename = "data.txt"
scriptname = "script.py"

a = os.listdir(os.getcwd())
a.remove(scriptname)
a.remove(datafilename)

fh = file(datafilename, "r")
b = fh.readlines()
fh.close()

for i in b:
    i = i.rstrip("\n")
    c1 = i.lower()
    c1 = c1.replace("-", " ")
    c1 = c1.replace("_", " ")
    for u in a:
        c2 = u.lower()
        c2 = c2.replace("-", " ")
        c2 = c2.replace("_", " ")
        if c1 == c2:
            print u + " -> " + i
            break
 
OP
C

compi

Member
Könnte man auch gleich noch in der Datei die Zeilen löschen die entweder als Datei schon vorhanden sind oder entsprechend umbenannt wurden?

Gruß
compi
 

abgdf

Guru
compi schrieb:
Könnte man auch gleich noch in der Datei die Zeilen löschen die entweder als Datei schon vorhanden sind oder entsprechend umbenannt wurden?
Jedenfalls die gefundenen sollten so "rausgelöscht" werden:
Code:
#!/usr/bin/env python
# coding: iso-8859-1

import os

datafilename = "data.txt"
scriptname = "script.py"

a = os.listdir(os.getcwd())
a.remove(scriptname)
a.remove(datafilename)

fh = file(datafilename, "r")
b = fh.readlines()
fh.close()

d = []

for i in b:
    x = 0
    i = i.rstrip("\n")
    c1 = i.lower()
    c1 = c1.replace("-", " ")
    c1 = c1.replace("_", " ")
    for u in a:
        c2 = u.lower()
        c2 = c2.replace("-", " ")
        c2 = c2.replace("_", " ")
        if c1 == c2:
            print u + " -> " + i
            x = 1
            break
    if not x:
        d.append(i)

fh = file(datafilename, "w")
for i in d:
    fh.write(i + "\n")
fh.close()
Gruß
 
OP
C

compi

Member
das script tut leider nichts.

Die Dateien haben die Endung .png

muss das noch mit eingearbeitet werden?

Gruß
compi
 

framp

Moderator
Teammitglied
compi schrieb:
das script tut leider nichts.
Dann musst Du es debuggen :roll:
Die Dateien haben die Endung .png

muss das noch mit eingearbeitet werden?
Du hast Dein Problem geschildert und abdgf hat Dir in python einen Vorschlag der Implementierung gemacht. Ich habe das Gefühl, Du kennst python nicht - korrigiere mich wenn ich falsch liege. Welche Programmiersprache kennst Du? Es macht keinen Sinn Dir ein Sample in einer Programmiersprache zu geben welche Du nicht kennst. Ansonsten bekommst Du weitere Vorschläge in bash, awk, Fortran, C, C++, Algol, Perl, Java, APL, COBOL, Pascal, PLI, Assembler, Smalltalk und sonstigen Programmiersprachen und Du kannst dann damit nichts anfangen :nosmile:
 
OP
C

compi

Member
mit Bash kenne ich mich etwas aus.

Mit Python überhaupt nicht.

Aber ich habe doch nur eine Funktion erfragt

wenn die läuft ist es mir egal in welcher Sprache es geschrieben wurde.

Gruß

compi
 

framp

Moderator
Teammitglied
compi schrieb:
... Aber ich habe doch nur eine Funktion erfragt.

wenn die läuft ist es mir egal in welcher Sprache es geschrieben wurde.
Ein Programm ist i.d.R. aber nie statisch, d.h. muss immer mal wieder an irgendwelche Ändeungen angepasst werden. Das geht aber nur wenn Du die Sprache kennst.
 
OP
C

compi

Member
Du hast sicher recht.

Aber ich möchte nur einmal ca 3000 Dateien umbenennen.

Und das händisch zu erledigen ist mit zu mühsam und deshalb dachte ich das mir einer mit einem Script unter die Arme greifen kann.

Gruß
compi
 

abgdf

Guru
compi schrieb:
das script tut leider nichts.
Hmm, es sollte zumindest die gefundenen Dateinamen in Deinem o.a. Format "a -> b" ausgeben.
In Python verschieben/umbenennen geht prinzipiell mit:
Code:
import shutil
shutil.move("von", "zu")
Aber wenn die Datenverarbeitung (noch) nicht klappt, hat es auch noch keinen Sinn, das zu implementieren.

In bash ist sowas sicher auch möglich, aber mir persönlich wäre die Datenverarbeitung dabei zu hakelig (soll heißen: ich schreib' nicht so gern in bash :) ).

Gruß
 

framp

Moderator
Teammitglied
abgdf schrieb:
...In bash ist sowas sicher auch möglich, aber mir persönlich wäre die Datenverarbeitung dabei zu hakelig (soll heißen: ich schreib' nicht so gern in bash :) ). ...
Der Aufwand wäre mir auch zu hoch. Würde ich nur in bash machen wenn ich das müßte. Python ist dazu gut geeignet.
 
A

Anonymous

Gast
Mir ist die bash zwar nicht zu hackelig ;) aber ich komme mit der Aufgabenstellung nicht ganz klar

compi schrieb:
Nun würde ich gerne die Dateinamen mit denen in der Textdatei abgleichen oder andersherum.
na was jetzt genau :???:

compi schrieb:
Die Textdatei ist dabei immer Namensgeber der Dateien.
sicher :D das gänge zwar bei Neuanlegen, aber beim Umbenennen haben die im Filesystem schon befindlichen Dateinamen da auch noch ein Wort mitzureden.siehe Kommentar bei Unschärfen.

compi schrieb:
Was die Unschärfe betrifft:
Unterschiede in der groß und klein Schreibweise, Leerzeichen können Bindestrich oder Underline sein.
was soll denn mit Dateien passieren die schon einen so ähnlichen Namen haben, knadenlos überschreiben oder lieber nicht ?
oder ist 100% sicher gestellt das bei der Verarbeitung aus der Datei keine solche Verwechslungen vorkommen kann zB. beim umbenennen einer Datei eine 2 Datei überschreiben die schon so heißt wie der Eintrag in der Datei, oder das ein Eintrag in der Datei auf 2 Dateinamen zutreffen könnte, so das die Gefahr besteht das eine davon überschrieben würde, und was soll mit Dateien passieren die nichts ähnliches in der Textdatei haben, oder ist 100%ig ausgeschlossen das es das nicht geben darf? Was passiert mit Dateinamen
Code:
Abc _- deF
wenn also mehrere der Unschafen Zeichen hintereinander aufkreuzen. Sind die Dateien in einem Verzeichnis oder in einem Dateibaum, ist dann in der Datei auch der Path mit angegeben und ist dieser ebenfalls unscharf. :???: Wie genau ist denn überhaupt die Datei mit den gewünschten Dateinamen erstellt worden ?

Ansonsten würde ich nicht mit umbenennen anfangen sondern mit "kopieren +umbenennen" in anderes Verzeichnis, und wenn geglückt dann löschen der Orginale. Dazu benötigt man allerdings Plattenplatz oder eine 100%sicheres Backup der orginal Dateien,

Das ist mir unter dieser unklaren und "unscharfen" Aufgabenstellung und Vorraussetzungen etwas zu riskant da was auf der bash dazu zu erfinden.

robi
 
OP
C

compi

Member
Ich habe mir die Dateinamen und die Einträge nochmal gründlich angeschaut.

Es gibt nur Unterschiede in der groß klein Schreibweise. Alle Dateinamen haben nur klein Buchstaben.

Alle Sonderzeichen sind richtig.

Ein umbenennen der vorhanden Dateien wäre mir am liebsten, ein Backup habe ich sowieso noch.

Gruß
compi
 
A

Anonymous

Gast
Na dann.
Code:
cat text.txt | while read D
 do
   d=$(echo $D | sed -e 's/\(^.*$\)/\L\1/' -e 's/[- _]/[-_ ]/g')

# echo -n "$D  : " ; find -iname "$d" | wc -l
  find -iname "$d" -exec echo -n "$D <---- " \; -print
# find -iname "$d" -exec mv {} "$D" \;

done

text.txt ist deine Dateinamensdatei und du musst vorher in das Verzeichnis wechseln in dem die Dateien sind. Ich hoffe mal die Dateien sind alle in einem Verzeichnis. (sonst solltest du find verbieten recursiv ins Verzeichnis abzusteigen.

Da sind 3 Arbeitszeilen , 2 sind auskommentiert.
Die nicht auskommentierte macht nur Ausgabe.
Code:
bla1 Bla1 <---- ./Bla1 Bla1
bla1 Bla1 <---- ./bla1 bla1
bLa2_bLa2 <---- ./bla2 Bla2
bLa2_bLa2 <---- ./bla2_bla2
bla3-Bla3 <---- ./Bla3 bla3
bla3-Bla3 <---- ./bla3-bla3
vorne steht der Name den die Datei hinten bekommen soll.

die erste auskommentiert Zeile ist auch nur zur Kontrolle. und zwar wieviele Dateien auf einen Eintrag in deiner Datei gefunden werden. Wenn es immer 1 ist dann ist es ok. bei 0 wurde keine Datei gefunden und alles größer 1 würde Dateien überschreiben.
Code:
bla1 Bla1  : 1
bLa2_bLa2  : 1
bla3-Bla3  : 1

die 2. auskommentierte Zeile benennt die Dateien dann wirklich um.

viel Erfolg.

robi
 

framp

Moderator
Teammitglied
@robi: Ich hatte auch schon mal irgendwann mal 5 Minuten überlegt wie ich das in bash machen würde - aber Dein eleganter Ansatz zeigt, dass ich von der bash absolut keine Ahnung habe :igitt:
:D
 
A

Anonymous

Gast
framp schrieb:
aber Dein eleganter Ansatz zeigt, dass ich von der bash absolut keine Ahnung habe
mach dir nichts draus, ich habe aber auch länger als 5 Minuten gebraucht um den Ansatz zu finden, ;) ;) ;) im Nachhinein, es geht noch kürzer und eleganter. ;) aber wir lassen es mal so stehen.

robi
 

abgdf

Guru
Find' ich auch super. :thumbs:

Bzgl. Vorsicht beim Umbenennen ist sonst noch "mmv" ganz gut: Das warnt, bzw. läßt die Dateien in Ruhe, wenn es da irgendwelche "Unschärfen" gibt. War bestimmt nicht leicht, dafür alle Regeln einzuarbeiten. Hat "mmv" dazu auch nicht gerade leichter in der Anwendung gemacht. Aber nötig war's sicher.
 
OP
C

compi

Member
Danke @robi

leider kommt nur

: not found
: not found
test.sh: 14: Syntax error: "done" unexpected (expecting "do")


das Script und die text.txt liegen zusammen mit den *.png Dateien in einem Ordner

Gruß
compi
 
A

Anonymous

Gast
Kann so deinen Fehler nicht nachvollziehen, vermute folgendes, du hast mit irgend beim kopieren aus dem Netz "Schmierzeichen" eingebaut oder mit einem ungeeigneten Editor das Script erstellt, oder gar versucht das Script abzuschreiben oder zu ändern und dabei Sonderzeichen falsch interpretiert oder vergessen.

hatten wir schön öfter. zB hier war es "NO-BREAK SPACE (0xA0)" , hin und wieder hatten wir auch Windows-Zeilenumbrüche und ähnliches Probleme mehr.

Kopiere das Script von deinem Browser, öffne den "vi" und füge dort das Script ein, und abspeichern. Dann mit
Code:
bash script
starten. Außerdem, dein Script hat in der Zeile 14 ein "done" zu dem es kein "do" findet, das Script was ich gepostet habe hat aber nur 7 Zeilen :???: :???: :???: :???: :???:
Hellsehen was du dort für Änderungen gemacht hast, kann ich von hier aus nicht.


robi
 
Oben