ubuntuusers.de

Dateien in Ordner durchnummerieren

Status: Gelöst | Ubuntu-Version: Ubuntu 18.04 (Bionic Beaver)
Antworten |

betzi1985

Anmeldungsdatum:
2. August 2018

Beiträge: 12

Hallo,

ich würde gerne alle Musikdateien die in einem Ordner sind durchnummerieren. Also die Dateinahmen so verändern, dass sie durchnummeriert werden.

Beispiel

Lied.mp3 LiedA.mp3

Soll später so sein 1. Lied.mp3 2. LiedA.mp3

Hat da jemand eine Idee, wie ich das Lösen kann???

Ich denke mal irge3ndwas mit ner Forschleife.

Danke und Grüß

Betzi

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4701

Wohnort: Berlin

@betzi1985: Da gibt's Software für. Schau Dir beispielsweise mal mmv an.

coram

Anmeldungsdatum:
17. Januar 2015

Beiträge: 645

Wohnort: Freiburg

Nach Wechsel in den Ordner mit den Musikdateien

cd /Pfad/zu/Musikordner

geht das mit einem eleganten Einzeiler 😉 :

ls | cat -n | while read nummer datei; do mv -n "$datei" "$nummer. $datei"; done

Hierbei erfolgt die Nummerierung der Dateien sortiert nach den ursprünglichen Dateinamen. Ist eine andere Sortierung erwünscht, bekommst Du das evtl. mit einer passenden ls-Option hin.

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4701

Wohnort: Berlin

@coram: Die Ausgabe von ls zu verarbeiten würde ich nicht als elegant, sondern als kaputt bezeichnen. Es gibt so einiges in Dateinamen was das auf die Nase fallen lassen kann. Zudem gibt es hier keinen Schutz vor überschreiben von bereits vorhandenen Dateinamen. Und vor Ordnern macht das auch keinen Halt.

Ungetestet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/bash

i=0
while IFS= read -r filename; do
    target="$i. $(basename "$filename")"
    if [[ -e $target ]]; then
        echo "'$target' exists! Not moving '$filename'"
    else
        echo mv "$filename" "$target"
        ((i++))
    fi
done < <(find . -maxdepth 1 -type f -name '*.mp3' -print0)

coram

Anmeldungsdatum:
17. Januar 2015

Beiträge: 645

Wohnort: Freiburg

Marc_BlackJack_Rintsch schrieb:

@coram: Die Ausgabe von ls zu verarbeiten würde ich nicht als elegant, sondern als kaputt bezeichnen. Es gibt so einiges in Dateinamen was das auf die Nase fallen lassen kann. Zudem gibt es hier keinen Schutz vor überschreiben von bereits vorhandenen Dateinamen. Und vor Ordnern macht das auch keinen Halt.

Das Überschreiben von Dateien wird in meinem Befehl durch die mv-Option -n unterbunden (aus der Manpage: -n, --no-clobber do not overwrite an existing file). Ansonsten bin ich zugegebenermaßen davon ausgegangen, dass sich im fraglichen Ordner nichts außer den mp3-Musikdateien befindet. Sollen vorhandene andere Dateien inklusive Unterordnern ausgeschlossen werden, ließe sich der ls-Befehl entsprechend ergänzen: ls *.mp3 ...

Ungetestet:

Na ja, ich habe mir wenigstens die Mühe gemacht, meine Lösung zu testen. Dein Skript funktioniert in meinem Testordner mit Musikdateien übrigens nicht ...

charly-ax

Avatar von charly-ax

Anmeldungsdatum:
19. März 2013

Beiträge: 1824

betzi1985 schrieb:

Lied.mp3 LiedA.mp3

Soll später so sein 1. Lied.mp3 2. LiedA.mp3

Das geht auch grafisch mit Bordmitteln. Nautilus kann das von Haus aus.

  • Du markierst alle Titel, die umbenannt werden sollen,

  • gehst auf "Umbenennen" oder F2.

  • Im aufklappenden Fenster gehst du auf "Umbenennen anhand einer Vorlage",

  • setzt dann den Cursor an den Anfang der Zeile,

  • gehst auf "+ Hinzufügen" und wählst die gewünschte Nummerierung aus,

  • setzt hinter die Nummerierung noch einen Punkt oder was du sonst noch willst (z.B. ein Leerzeichen)

  • und klickst abschließend oben rechts auf "Umbenennen".

Du erhältst dabei eine Vorschau des neuen Dateinamens. (siehe auch Screenshot anbei)

Edit: Ich sehe gerade dein Anmeldedatum. Willkommen bei ubuntuusers.

Bilder

betzi1985

(Themenstarter)

Anmeldungsdatum:
2. August 2018

Beiträge: 12

Danke charly-ax für die freundliche Aufnahme, ich bin auf dem Linuxgebiet Anfänger und hoffe ich stelle nicht zu dumme einfache Fragen.

Gruß betzi

PS: ich habe eine Anleitung gefunden, wie ich mein Ubuntu wie MACOS aussehen lassen kann, ist das sicher? Ist das zu empfehlen?

charly-ax

Avatar von charly-ax

Anmeldungsdatum:
19. März 2013

Beiträge: 1824

betzi1985 schrieb:

hoffe ich stelle nicht zu dumme einfache Fragen.

Eigentlich gibt es aus meiner Sicht kaum dumme Frage, eher mehr dumme Antworten.

PS: ich habe eine Anleitung gefunden, wie ich mein Ubuntu wie MACOS aussehen lassen kann, ist das sicher? Ist das zu empfehlen?

Dazu solltest du ein neues Thema eröffnen. Beschreibe dazu gleich mehr Details zu deinem bisherigen Vorgehen. (siehe bitte auch Richtig fragen)

Gruß, Holger

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4701

Wohnort: Berlin

@coram: Eine Lösung mit ls kann man nicht reparieren, ausser wenn man ls durch etwas anderes ersetzt das die Dateinamen durch etwas trennen kann was garantiert nicht in einem Dateinamen vorkommen kann. Also beispielsweise find. Deine while-Schleife hat das Problem das sie Backslashes in der Eingabe interpretiert und „word splitting“ vor dem Aufteilen auf die beiden Namen betreibt.

Getestet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/bash

i=0
while IFS='' read -r -d '' filename; do
    target="$i. $(basename "$filename")"
    if [[ -e $target ]]; then
        echo "'$target' exists! Not moving '$filename'"
    else
        echo mv "$filename" "$target"
        ((i++))
    fi
done < <(find . -maxdepth 1 -type f -name '*.mp3' -print0)

coram

Anmeldungsdatum:
17. Januar 2015

Beiträge: 645

Wohnort: Freiburg

@Marc_BlackJack_Rintsch: Dein Skript ist jetzt, wo es funktioniert, ohne Zweifel perfekter als mein Einzeiler. Als Autodidakt und Hobby-Coder will ich mich gegenüber einem vermeintlichen Profi (?) auch keinesfalls zu weit aus dem Fenster lehnen. Das Problem des eher unwahrscheinlichen Falles, dass ein Dateiname Backslashes enthält, glaube ich gleichwohl "reparieren" zu können – diesmal mit einer Option für read:

ls *.mp3 | cat -n | while read -r nummer datei; do mv -n "$datei" "$nummer. $datei"; done

Nachtrag: Wie ich erst jetzt sehe, nutzt ja auch Dein Skript die read-Option -r. 😉 Das heißt, im Grunde kommt auch find – genauso wie ls – nicht ohne nachträgliche "Reparatur" aus, oder? 😲

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4701

Wohnort: Berlin

@coram: Das mit den Backslashes ist ein Problem der Schleife wie ich ja geschrieben habe, also weder von ls noch von find. Nun gibt's aber immer noch Probleme mit dem „word splitting“ und mit Zeilenumbrüchen in Dateinamen…

Neral

Anmeldungsdatum:
3. Oktober 2007

Beiträge: 230

Alternativvorschlag in einer „richtigen“ Programmiersprache, der die lästigen Probleme der Shell nicht hat (ungetestet und Python 3.6+):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/python3

import shutil
import sys
from pathlib import Path


def move_mp3s(directory):
    i = 0
    for path in filter(Path.is_file, Path(directory).glob("*.mp3")):
        target = path.parent / f"{i}. {path.name}"
        if target.exists():
            print(f"`{target}` already exists, skipping `{path}`.")
        else:
            print(f"Moving `{path}` → `{target}`")
            # shutil.move(path, target)
            i += 1


def main():
    try:
        directory = sys.argv[1]
    except IndexError:
        directory = "."
    move_mp3s(directory)


if __name__ == "__main__":
    main()

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4701

Wohnort: Berlin

Lösung in Tcl:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#!/bin/sh
# \
exec tclsh "$0" "$@"

set folder [if {$argc > 0} { lindex $argv 0 } else { list . }]

set number 1
foreach path [glob -nocomplain -type f -directory $folder *.mp3] {
    set target [file join [file dirname $path] \
                          [format "%d. %s" $number [file tail $path]]]
    if {[file exist $target]} {
        puts [format "`%s` already exists. Skipping `%s`." $target $path]
    } else {
        file rename -- $path $target
        incr number
    }
}
Antworten |