• 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] cp steigt aus wegen Klammern

Vorbemerkung:
Es handelt sich nachfolgend um Dateien die mit streamripper aus den Streams legaler Radiosender erzeugt wurden,
bzw. aus meiner eigenen CD Sammlung.


Hallo,
Ich bin gerade dran, mir ein script zu basteln, welches mir aus einer Listendatei (musikliste.txt) eine Zufallszeile auswählt.
Das Schreiben des Skriptes ist (auch dank der hier im Forum vorhandenen Dokumentation und Google) kein größeres Problem.
Die Datei mit den Pfaden zu den Titeln erzeuge ich mittels:
Code:
find /run/media/ingo/SEAGATE_1TB/Musik -name '*.mp3'>/home/ingo/musikliste.txt
Dann möchte ich den Pfad an cp übergeben und in einer Schleife 999 Zufallsdateien auf einen USB Stick kopieren
(999 deshalb, weil der mistige (Hardware) Player nur bis zu 999 Dateien "sieht" und zufällig abspielen kann.)
Aus historischen Gründen (streamripper) sind aber nun leider gammelige Pfadkonstrukte wie diese enthalten:
Code:
/run/media/ingo/SEAGATE_1TB/Musik/AC-DC/AC-DC Complete Collection/AC-DC-Mix/AC-DC - Let Me Put My Love Into You [Requested by motordave- -AC-DC Rocks! Cheers to everyone in Rock Radio 1!-].mp3
Ich brauche wohl niemandem zu erzählen was cp mit [ { oder ( im Dateipfad macht... :(
Die Frage:
Muss ich jetzt alle 40.000 .mp3s so umbenennen daß cp nicht mehr drüber stolpert?
Oder kann man die illegalen Zeichen irgendwie "maskieren"??
 
Hallo ingo.trautwein,

ingo.trautwein schrieb:
Code:
/run/media/ingo/SEAGATE_1TB/Musik/AC-DC/AC-DC Complete Collection/AC-DC-Mix/AC-DC - Let Me Put My Love Into You [Requested by motordave- -AC-DC Rocks! Cheers to everyone in Rock Radio 1!-].mp3
Dann entferne doch die Klammern aus den Dateinamen:
Code:
for a in *.mp3; do mv "$a" "$(echo $a | sed 's/[//g')"; done
for a in *.mp3; do mv "$a" "$(echo $a | sed 's/]//g')"; done
Damit es nicht zu weiteren Problemen kommt ersetzt Du dann die Leerzeichen am besten auch gleich durch Unterstriche:
Code:
for a in *.mp3; do mv "$a" "$(echo $a | sed 's/ /_/g')"; done
Mit sed kannst Du natürlich auch gleich alle anderen "Problemzeichen" entfernen.

ingo.trautwein schrieb:
Ich brauche wohl niemandem zu erzählen was cp mit [ { oder ( im Dateipfad macht... :(
Muss ich jetzt alle 40.000 .mp3s so umbenennen daß cp nicht mehr drüber stolpert?
Oder kann man die illegalen Zeichen irgendwie "maskieren"??
Das Umbenennen geht doch mit einem Script in wenigen Sekunden.
Ja man kann, dazu muss man diese escapen, also mit einem Backslasch '\' als normale Zeichen deklarieren:
Code:
herz-von-hessen@openSUSE-Desk:~> ls|head
AC-DC - Let Me Put My Love Into You [Requested by motordave- -AC-DC Rocks! Cheers to everyone in Rock Radio 1!-].mp3

herz-von-hessen@openSUSE-Desk:~> cp AC-DC\ -\ Let\ Me\ Put\ My\ Love\ Into\ You\ \[Requested\ by\ motordave-\ -AC-DC\ Rocks\!\ Cheers\ to\ everyone\ in\ Rock\ Radio\ 1\!-\].mp3 AC-DC\ -\ Let\ Me\ Put\ My\ Love\ Into\ You\ \[Requested\ by\ motordave-\ -AC-DC\ Rocks\!\ Cheers\ to\ everyone\ in\ Rock\ Radio\ 1\!-\]TEST.mp3

herz-von-hessen@openSUSE-Desk:~> ls|head
AC-DC - Let Me Put My Love Into You [Requested by motordave- -AC-DC Rocks! Cheers to everyone in Rock Radio 1!-].mp3
AC-DC - Let Me Put My Love Into You [Requested by motordave- -AC-DC Rocks! Cheers to everyone in Rock Radio 1!-]TEST.mp3

Lieben Gruß aus Hessen
 

framp

Moderator
Teammitglied
ingo.trautwein schrieb:
...Ich brauche wohl niemandem zu erzählen was cp mit [ { oder ( im Dateipfad macht... :(
Die Frage:
Muss ich jetzt alle 40.000 .mp3s so umbenennen daß cp nicht mehr drüber stolpert?
Oder kann man die illegalen Zeichen irgendwie "maskieren"??
Zwei Dinge fallen mir da ein:
1) per sed alle Metazeichen escapen, d.h. mit einem vorangehenden \ versehen
2) Es gibt auch die Moeglichkeit in der bash diese Metazeicheninterpretation aususchalten (Hatte letztens mal jemand in einem anderen Forum gepostet). Nur leider kann ich mich nicht im Detail erinnern wie es ging. Vermutlich findet man da was bei man bash irgendwo :)

UPDATE: According man bash: set -f disabled die pathname expansion ;)

UPDATE2: Habe gerade die Antwort von HvH gelesen.
Code:
sed 's/([]\[(){} ])/\\\1/g'
escaped alle Metachars in einem Rutsch ;)
 

leanUX

Member
Hier mal versuchsweise eine Variante, die ohne Escapen auskommt
und stattdessen mittels Inode-Nummern arbeitet:

Code:
#/bin/bash


## zuerst werden einige mp3 - Test-Dateien mit huebschen (Verzeichnis-)Namen angelegt 
#  Datei ~/Musik/song.mp3 sollte vorhanden sein

# Test-Verzeichnisse unter /tmp anlegen
mkdir -p /tmp/musik
mkdir -p /tmp/usbstick


mkdir -p '/tmp/musik/AC-DC/AC-DC Complete Collection/AC-DC-Mix/'
cp ~/Musik/song.mp3 '/tmp/musik/AC-DC/AC-DC Complete Collection/AC-DC-Mix/Let Me Put My Love Into You [Requested by motordave- -AC-DC Rocks! Cheers to everyone in Rock Radio 1!-].mp3'

mkdir "/tmp/musik/ -- 'foo' -- 'bar' (blah) [fasel] .. %"
cd "/tmp/musik/ -- 'foo' -- 'bar' (blah) [fasel] .. %"
cp ~/Musik/song.mp3 'eins zwei drei - - vier fünf sechs!! -[cool].mp3'

mkdir -p '/tmp/musik/a "b" ^$ #'
cp ~/Musik/song.mp3 '/tmp/musik/a "b" ^$ #/!! !! ( - ) .. [ ## ] -- blah-song.mp3'
cp ~/Musik/song.mp3 '/tmp/musik/a "b" ^$ #/abc %% $$ ## "" () [] -- weirdnamedsong  .mp3'
cp ~/Musik/song.mp3 '/tmp/musik/a "b" ^$ #/this is another [(very) strange named] song -- unkown artist!! [-unknown album-!].mp3'
# 5 Dateien wurden angelegt   (4 davon werden nun zufaellig ausgewaehlt und kopiert)




## jetzt werden NUM_FILES anhand der Inode-Nummern von /tmp/musik
#  nach /tmp/usbstick kopiert
NUM_FILES=4   # Anzahl der zu kopierenden Dateien

# Inode-Nummern der mp3-Dateien ermitteln, 
# Reihenfolge durchmischen und die ersten NUM_FILES
# anhand ihrer Inode-Nummern kopieren 
for INODE_NR in $(ls -i -R /tmp/musik | grep  'mp3$' | shuf | cut -f 1 -d ' ' | head -n $NUM_FILES)
do
  find /tmp/musik -inum $INODE_NR -exec cp {} /tmp/usbstick/ \;
done


Was halten die Experten von diesem Ansatz?

Grüße
 
A

Anonymous

Gast
ingo.trautwein schrieb:
Ich brauche wohl niemandem zu erzählen was cp mit [ { oder ( im Dateipfad macht... :(
Doch
Code:
robi@LINUX #> ls -l *.mp3
-rw-r--r-- 1 robi users 0 17. Feb 13:56 A[{(b)}]\C+127*34.mp3
robi@LINUX #> cp 'A[{(b)}]\C+127*34.mp3' neu.mp3
robi@LINUX #> find -name "A*.mp3" -exec cp {} neu1.mp3 \;
robi@LINUX #> cp "A[{(b)}]\C+127*34.mp3" neu2.mp3
robi@LINUX #> ls -l *.mp3
-rw-r--r-- 1 robi users 0 17. Feb 13:56 A[{(b)}]\C+127*34.mp3
-rw-r--r-- 1 robi users 0 17. Feb 13:59 neu2.mp3
-rw-r--r-- 1 robi users 0 17. Feb 13:59 neu1.mp3
-rw-r--r-- 1 robi users 0 17. Feb 13:59 neu.mp3
funktioniert doch alles wie geschmiert ;) und würde auch in sehr vielen anderen Reihenfolgen der Sonderzeichen und Varianten sauber funktionieren.
Alles nur Vorurteile, cp kann mit jedem Zeichen im Path und Dateinamen umgehen außer '\0' und '/' nur die User können es nicht richtig in der bash und in Scripten schon gleich 2 x nicht.

Allerdings wirst du wenn du sowas 1zu 1 von Linux mit unberechenbaren Sonderzeichen auf einen handelsüblichen MP3.Player kopierst, dort auch mit Problemen rechnen müssen, denn das Dateisystem dort versteht auch nur die Hälfte von dem was Linux dort alles an Sonderzeichen rüber kopieren könnte.

Das Beste ist auf alle Falle mal in den sauren Apfel beißen und die Path und Dateinamen mal aufräumen, mit Scripten und Befehlszeilen und auch mit der Hand. Sch... - Arbeit, aber nur so lernt man auch in der Zukunft sowas dann gleich nach dem Anlegen sauber zu korrigieren. ;)

robi
 

framp

Moderator
Teammitglied
robi schrieb:
...Das Beste ist auf alle Falle mal in den sauren Apfel beißen und die Path und Dateinamen mal aufräumen, mit Scripten und Befehlszeilen und auch mit der Hand. Sch... - Arbeit, aber nur so lernt man auch in der Zukunft sowas dann gleich nach dem Anlegen sauber zu korrigieren. ;)
Auf welche Zeichen sollte man sich da in den Dateinamen beschraenken?
 
Hallo robi,

robi schrieb:
Alles nur Vorurteile, cp kann mit jedem Zeichen im Path und Dateinamen umgehen außer '\0' und '/'
Hmm, da kann man ja
Code:
ls -Q1
benutzen um die Dateinamen zu Quoten, in Verbindung mit find & exec wäre damit alles ohne eine Änderung der Dateinamen machbar.

Lieben Gruß aus Hessen
 
@framp
wenn ich etwas (wichtiges) neu anlege verzichte ich auf Leerzeichen und Umlaute, natürlich auch auf jede Art von Klammer.
(Ich bin da etwas paranoid, weil mir mal ein (Nicht Linux) Backup-Programm unter W*N Dateien mit Umlauten zerschossen hat.)
Dummerweise erzeugt der Streamripper so krumme Dateinamen.
Wahrscheinlich kann man das aber auch irgendwo konfigurieren (gehört aber nicht in dieses Forum), wie
z.B. die Fileaugabe von lame o.ä.

EDIT:
Nach einer beherzten rekursiven Anwendung von rename auf der Musikplatte läuft nun auch mein Skript.
 
A

Anonymous

Gast
framp schrieb:
Auf welche Zeichen sollte man sich da in den Dateinamen beschraenken?

Dafür gibt es wohl nur allgemeine Richtlinien, ich würde mal so formulieren:

* Dateinamen und Pathlänge und Pathtiefe sollten passend, aussagekräftig und sauber anzeigbar sein
* Musik/mp3/Interpret/Album/titel.mp3 alles was tiefer geht und sich nicht durch den Unterschied verschiedener Auflösungen oder Qualitäten unterscheidest, ist für die meisten Sammler schon zu viel
* Mehrfache Interpretennennung im Path und Titel sind zuviel
* Titel eindeutig, möglichst kurz und ohne weitere wenig nützliche Zusätze, außer man hat mehrere Versionen ein und des selben Titels.
* Bei Groß- Kleinschreibung sollte man ein klein bisschen ein System haben oder aber daran denken das eventuell abc01234.jpg beim mounten bestimmter Dateisysteme durchaus auch mal ABC01234.JPG sein kann, Dateien die also hier viel zwischen unterschiedlichsten Filesystemen hin und her verschoben/kopiert werden, sollten diesbezüglich eindeutig sein, damit sie sich nicht gegenseitig überschreiben können.

* Der gesamte Pathname mit Titel ab Verzeichnis "Musik" sollte möglichst nicht über eine typische Konsolzeilenlänge gehen.
* Der Dateiname sollte bei "ls -l" möglichst nicht über eine typische Konsolzeilenlänge gehen.

* Zeichen "A-Za-z0-9+_-;:#,." sind zu bevorzugen. wobei für "-" gilt, nicht am Anfang oder nach Leerzeichen, und für "." möglichst nur einmal als Trenner für die Extension. ; und : und "#" sind mit etwas Bedacht zu benutzen, nicht am Anfang und nicht nach Leerzeichen und eignen sich zB um eindeutige Bezeichnungen für ein und das selbe Dokument abzutrennen. Leerzeichen dürfen in Dokumenten, Musik, Videos und so weiter durchaus vorhanden sein, (sind Leerzeichen das einzige Sonderzeichen ist damit wunderbar umzugehen.)
* ÄÜÖäüöß im Path oder Dateinamen sind und bleiben ein Ärgernis beim Umkopieren oder Datenaustausch mit anderen Betriebs- und Filesystemen genau wie alle anderen Sonderzeichen aus anderen Sprachen.
* Die Sonderzeichen ' und " sowie\ und NEUEZEILE und alle Sonderzeichen die nicht druckbar sind oder man sonst wie nicht sofort erkennen würde sind in Datei und Pathnamen zu meiden wie der Teufel das Weihwasser (Beispiel \r oder \t)
* Sonderzeichen von denen bekannt ist, das sie irgendwo eine Sonderfunktion haben sollte man möglichst meiden oder sehr bedacht einsetzen
zB $&%?*~<>()[]{}| diese Zeichen an sich sind bei entsprechender Behandlung in der Bash nicht kritisch aber im Dateinamen auch nicht wirklich so aussagefähig, dass man sie unbedingt einsetzen müsste.

Ansonsten gilt, Dateinamenskonventionen die man sich bei MP3 auferlegt, müssen nicht die selben sein die man sich bei Dokumenten auferlegen muss, oder bei Bilder bereit ist zu akzeptieren. Letztlich muss jeder selbst wissen was er für praktisch hält, wer viel damit arbeiten muss und dort klare Strukturen und Verhältnisse auf dem Rechner pflegt kann sich über die Zeit ne ganze Menge Zeit und Ärger sparen.

robi
 

framp

Moderator
Teammitglied
Danke robi für die detaillierte Antwort. Bislang habe ich bewusst immer nur a-A-Z0-9 und _ als Leerzeichenersatz benutzt um Problemen aus dem Wege zu gehen und bin damit sehr gut gefahren. Sinnvoll in Dateinamen ist aber vielleicht noch + und - sowie : als Blickfang. Die werde ich dann wohl zukünftig noch mitbenutzen.
 
Oben