staging.inyokaproject.org

Ersten Buchstaben von Dateien in Großbuchstaben wandeln

Status: Ungelöst | Ubuntu-Version: Ubuntu 21.04 (Hirsute Hippo)
Antworten |

Multimedia4Linux

Anmeldungsdatum:
9. April 2007

Beiträge: 45

Hallo, ich würde gerne den ersten Buchstaben alles Dateien in einem Verzeichnis mit einem Großbuchstaben versehen. Wie setze ich so etwas in einem Skript um, damit ich nicht alle Dateien einzeln umbenennen muss?

Danke

DJKUhpisse Team-Icon

Supporter, Wikiteam
Avatar von DJKUhpisse

Anmeldungsdatum:
18. Oktober 2016

Beiträge: 18245

Der erste Buchstabe soll also durch den gleichen Buchstaben in groß ersetzt werden? Also die Datei test.txt soll in Test.txt umbenannt werden?

Man könnte da

ls 

nutzen für die Ausgabe. Beachte auch evtl. versteckte Dateien, die beginnen mit einem Punkt.

Dann müsste man den String trennen und dann den Buchstaben durch einen großen ersetzen. Das könnte man dann in eine Liste packen und das mit

mv

erledigen lassen bzw. erstmal die Befehle ausgeben lasen zur Prüfung, das dann einzufügen und abzuschicken sollte nicht das Problem sein.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

1
for f in *; do echo mv "$f" "${f^}"; done 

Ich würd's nicht machen. Großbuchstaben haben alle die gleiche Höhe und sind daher optisch weniger signifikant, als Kleinbuchstaben, die sich bezüglich Ober- und Unterlängen unterscheiden können.

Außerdem musst Du beim Tippen immer die Shifttaste drücken, was gerade wegen der Autovervollständigung von Dateinamen sehr lästig ist.

Achso - der Beispielcode oben benennt nicht um, sondern zeigt nur die Kommandos. Das echo muss weg, um ernstzumachen. Evtl. schon existierende Dateien des Namens werden ohne Nachfrage stillschweigend überschrieben - Abhilfe schafft da der Schalter -i für interaktiv, alias "beim User nachfragen, wenn im Zweifel", näheres sie man mv.

Wegen der Gefahr von Leerzeichen und üblerem in Dateinamen muss von ls abgeraten werden.

frechdachs

Anmeldungsdatum:
3. Juni 2013

Beiträge: 120

Multimedia4Linux schrieb:

Hallo, ich würde gerne den ersten Buchstaben alles Dateien in einem Verzeichnis mit einem Großbuchstaben versehen. Wie setze ich so etwas in einem Skript um, damit ich nicht alle Dateien einzeln umbenennen muss?

Auf die Schnelle:

1
2
3
4
5
6
7
8
for datei in *
do
     EINS=$(echo "${datei}" | cut -c 1 | tr [:lower:] [:upper:])
     ZWEI=$(echo "${datei}" | cut -c 2-)
     echo "Name alt: ${datei}"
     echo "Name neu: "${EINS}${ZWEI}"
     #mv "${datei}" "${EINS}${ZWEI}"
done

Wenn die Vorschau passt, dann einfach das "#"-Zeichen in Zeile 7 entfernen. Das Script berücksichtigt keine versteckten Dateien (also die Files, die mit einem Punkt anfangen).

Danke

Liebe Grüße,

frechdachs

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

frechdachs schrieb:

1
2
3
4
5
6
7
8
for datei in *
do
     EINS=$(echo "${datei}" | cut -c 1 | tr [:lower:] [:upper:])
     ZWEI=$(echo "${datei}" | cut -c 2-)
     echo "Name alt: ${datei}"
     echo "Name neu: "${EINS}${ZWEI}"
     #mv "${datei}" "${EINS}${ZWEI}"
done

Deine Version funktioniert freilich auch - bis auf die ungerade Zahl doppelter Anführungsstriche in Zeile 6.

Zum Trost, dass ich schneller und kürzer war, verrate ich Dir, wie Du EINS und ZWEI (Kopf und Rest würden ja besser passen) billiger haben kannst:

1
2
kopf=${datei:0:1}
rest=${datei:1}

Wertvolle Gedankenstütze ist hier die bash manpage, Abschnitt Parameter Expansion - muss man lange scrollen, um da hin zu gelangen, aber es lohnt sich. ☺

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Oder mit Python3 mit der Möglichkeit mehr als ein Verzeichnis anzugeben inkl. Prüfung, ob die Zieldatei bereits existiert:

1
2
3
4
5
6
7
#!/usr/bin/env python3
from pathlib import Path
import sys

for d in filter(lambda x: x.is_dir(), (Path(d) for d in sys.argv[1:])) if sys.argv[1:] else (Path("."),):
    for f in filter(lambda x: x.is_file() and not Path(x.name.capitalize()).exists(), Path(directories).iterdir()):
        f.rename(f.name.capitalize())

frechdachs

Anmeldungsdatum:
3. Juni 2013

Beiträge: 120

user_unknown schrieb:

frechdachs schrieb:

1
2
3
4
5
6
7
8
for datei in *
do
     EINS=$(echo "${datei}" | cut -c 1 | tr [:lower:] [:upper:])
     ZWEI=$(echo "${datei}" | cut -c 2-)
     echo "Name alt: ${datei}"
     echo "Name neu: "${EINS}${ZWEI}"
     #mv "${datei}" "${EINS}${ZWEI}"
done

Deine Version funktioniert freilich auch - bis auf die ungerade Zahl doppelter Anführungsstriche in Zeile 6.

Oha! Stimmt. Habe ich auf die Schnelle übersehen...

Zum Trost, dass ich schneller und kürzer war, verrate ich Dir, wie Du EINS und ZWEI (Kopf und Rest würden ja besser passen) billiger haben kannst:

1
2
kopf=${datei:0:1}
rest=${datei:1}

Wertvolle Gedankenstütze ist hier die bash manpage, Abschnitt Parameter Expansion - muss man lange scrollen, um da hin zu gelangen, aber es lohnt sich. ☺

In der Tat - das ist ein wertvoller Hinweis. Das war mir nicht bekannt. Vielen Dank!

Liebe Grüße,

frechdachs

hellmi666

Avatar von hellmi666

Anmeldungsdatum:
30. August 2007

Beiträge: 238

Wenn du lieber mit einer GUI arbeitest, dann kann das auch "gprename".

In den entsprechenden Ordner navigieren, Reiter: Fallunterscheidung, "Nur der erste Buchstabe" auswählen, umbenennen, fertig.

snafu1

Avatar von snafu1

Anmeldungsdatum:
5. September 2007

Beiträge: 2136

seahawk1986 schrieb:

Oder mit Python3 mit der Möglichkeit mehr als ein Verzeichnis anzugeben inkl. Prüfung, ob die Zieldatei bereits existiert:

1
2
3
4
5
6
7
#!/usr/bin/env python3
from pathlib import Path
import sys

for d in filter(lambda x: x.is_dir(), (Path(d) for d in sys.argv[1:])) if sys.argv[1:] else (Path("."),):
    for f in filter(lambda x: x.is_file() and not Path(x.name.capitalize()).exists(), Path(directories).iterdir()):
        f.rename(f.name.capitalize())

Zunächst einmal würde ich hierfür ohne Grund eher nicht zu Python greifen, da in dem Fall deutlich mehr Code nötig ist als mit den Shell-Tools.

Und wenn doch, dann sollte IMHO zumindest die Möglichkeit eingebaut werden, das Skript auch aus einem anderen Verzeichnis aufzurufen, ohne dass die neuen Dateinamen im Arbeitsverzeichnis landen, statt im besagten anderen Verzeichnis. Denn das passiert bei einem simplen f.name.capitalize() leider. Damit sowas schnell auffällt, kann man mit Path.resolve() den neuen Pfad auflösen.

Auch vom Code-Stil würde ich einige Dinge anders machen und lande dann in etwa bei dem hier:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pathlib import Path

def capfiles(path):
    return (
        entry.replace(entry.parent / entry.name.capitalize())
        for entry in path.iterdir() if entry.is_file()
    )

def make_testdir():
    testdir = Path("testdir")
    testdir.mkdir(exist_ok=True)
    for name in ("spam", "ham", "eggs"):
        (testdir / f"{name}.txt").touch()
    return testdir

def main():
    testdir = make_testdir()
    for new_path in capfiles(testdir):
        print(new_path.resolve())

if __name__ == "__main__":
    main()

Das Skript legt ein Testverzeichnis an und löscht es bewusst nicht, damit man die Ergebnisse auch nach dem Aufruf noch sehen kann. Bereits gleich benannte Dateien werden stillschweigend überschrieben, wenn sie der Version mit dem Großbuchstaben entsprechen. Es kommt auch (genau wie deine Version) mit Leerzeichen, Newlines und ähnlichen "bösen" Zeichen klar.

Multimedia4Linux

(Themenstarter)

Anmeldungsdatum:
9. April 2007

Beiträge: 45

Danke an alle. Hat mir sehr geholfen.

Gerd_A

Anmeldungsdatum:
10. September 2020

Beiträge: 298

Falls es für den einen oder anderen noch interessant ist;

Im "The Linux Cookbook" bin ich auf Perl Script mit dem Namen "chcase"

(http://www.primaledge.ca/chcase.html)

aufmerksam geworden dass u.A. auch die gewünschte Funktion enthält.

Antworten |