Bash - Archivname zu Dateiname, unsachgemäße Zuordnung (zip, cdg, mp3)

Dec 07 2020

Ich habe ein Skript geschrieben, das in einem Zip-Archiv nach zwei bestimmten Erweiterungen sucht. Es werden einige Überprüfungen durchgeführt, um festzustellen, ob das Archiv nur zwei Dateien enthält, und diese dann zu verarbeiten. Wenn das Archiv weniger als 2 hat, wird das Archiv in einen "BAD" -Ordner verschoben. Wenn das Archiv mehr als 2 hat, wird das Archiv in ein "FIX" -Verzeichnis verschoben.

Der Prozessschritt besteht darin, die Dateien zu extrahieren und in denselben Namen umzubenennen, den das Zip-Archiv hat.

Dies alles funktioniert gut, wenn die Bedingungen perfekt sind. Aber wenn sie nicht perfekt sind ... wird es hässlich.

Ich stoße auf einen Fall, in dem die Dateien zwar die richtigen 2 Dateien und die richtige Erweiterung haben, aber Sonderzeichen (wie Ø, Backticks, Komma, Apostroph usw.) Verarbeitet werden (ich nehme an) wie Regex-Syntax oder Ausdrücke.

Hier ist der Code:

#! /bin/bash

prefix="0000_"

mkdir -p ${prefix}{DONE,FIX,BAD} shopt -s nocaseglob for i in *.ZIP; do zip_name="$i"
        pair_exists=$(unzip -Z1 "$i" | grep -E -- '.cdg|.CDG|.mp3|.MP3' | wc -l)
        log="${prefix}LOG.txt" if [ $pair_exists -eq 2 ]
            then
                cdg_name=$(unzip -Z1 "$i" | grep -E -- '.cdg|.CDG' | awk '{print substr($0,index($0,$1))}') mp3_name=$(unzip -Z1 "$i" | grep -E -- '.mp3|.MP3' | awk '{print substr($0,index($0,$1))}')
                new_cdg_name="$(echo "${zip_name%.*}.cdg")"
                new_mp3_name="$(echo "${zip_name%.*}.mp3")"
                7za x "$i" -aoa -y -ba >> ./$log
                mv ./"$cdg_name" ./"$new_cdg_name"
                mv ./"$mp3_name" ./"$new_mp3_name"
                mv ./"$zip_name" ./${prefix}DONE/

        elif [ $pair_exists -gt 2 ] then echo "" echo "NEEDS FIXED: $zip_name"
                mv ./"$zip_name" ./${prefix}FIX/

        elif [ $pair_exists -lt 2 ] then echo "" echo "ARCHIVE IS BAD: $zip_name"
                mv ./"$zip_name" ./${prefix}BAD/

        else
                echo ""
                echo "MUST BE BROKE!"
                echo ""
        fi
    done
exit

Alles ist cool, bis ich zu den mv-Aussagen komme.

                mv ./"$cdg_name" ./"$new_cdg_name"
                mv ./"$mp3_name" ./"$new_mp3_name"

Ich habe das Gefühl, dass mv hier möglicherweise nicht die richtige Methode ist, aber ich hatte auch ernsthafte Probleme mit der Umbenennung. Ich denke eher, dass ich einen Code brauche, der den Befehlen sagt, dass sie keine Zeichen innerhalb der Variablen als auszuführende Aktionen behandeln sollen.

Folgendes sehe ich ...

----- BEISPIEL 1 -----

ZIP-DATEINAME: 

     CB30035-05 - EINFACHER PLAN - Ich würde alles tun

DATEIEN INNERHALB DER PLZ:

     CB30035-05 - Einfacher Plan - Ich würde alles tun.cdg
     CB30035-05 - Einfacher Plan - Ich würde alles tun.mp3

ERROR:

     mv: kann nicht stat './CB30035-05 - Simple PlanI \' d Do Anything.cdg ': Keine solche Datei oder kein solches Verzeichnis
     mv: kann nicht stat './CB30035-05 - Simple PlanI \' d Do Anything.mp3 ': Keine solche Datei oder kein solches Verzeichnis

----- BEISPIEL 2 -----

ZIP-DATEINAME:

     CBSE5-0068 - CARPENTERS, THE - FÜR ALLES, WAS WIR WISSEN.zip

DATEIEN INNERHALB DER PLZ:

     cbscdge450-5-0068 - Tischler - Nach allem, was wir wissen.cdg
     cbscdge450-5-0068 - Tischler - Nach allem, was wir wissen.mp3

ERROR:
mv: kann nicht stat './cbscdge450-5-0068 - Tischler - Für alles, was wir wissen.cdg \ ncbscdge450-5-0068 - Tischler - Für alles, was wir wissen.mp3': Keine solche Datei oder kein solches Verzeichnis

Ich habe nach einem ähnlichen Problem gesucht, aber die gefundenen Themen passten nicht wirklich zu meinem Problem, oder ein Teil des Codes ging mir etwas über den Kopf, um herauszufinden, wie ich es in mein Skript integrieren kann.

Ich würde mich über jede Hilfe freuen. Dankeschön!

(HINWEIS: Ich bin mir bewusst, dass mein "awk" im obigen Skript nichts tut. Ich bin zu "unzip -Z1" gewechselt und das scheint meine vorherigen Bemühungen gelöst zu haben, nur den Dateinamen aus den Zip-Dateien zu entfernen. Ich bin gegangen es in und angepasst, nur um es zu behalten, falls ich es brauchte.)



EDIT 2020120601:


Als Antwort auf @Wieland habe ich das doppelte Leerzeichen aus dem Namen der Zip-Datei entfernt. Aber ließ den doppelten Platz auf den Dateien im Inneren. Ich werde nicht in der Lage sein, das Innere jeder Datei zu reparieren, da es zu viele gibt, also muss ich herausfinden, wie ich sie so reparieren kann, wie sie sind. Das Entfernen des doppelten Speicherplatzes in der Zip-Datei hat meine Ergebnisse nicht verändert.

Als Antwort auf @steeldriver finden Sie hier einige weitere Informationen. Unten finden Sie die Rückgabe für jeden Befehl, den ich zu verwenden versucht habe (beachten Sie, dass 7za ... nicht nur Dateinamen erzeugt, daher habe ich zuvor awk verwendet).

Ich habe auch den Code zum Lesen geändert und dies hat meine Ergebnisse nicht geändert, aber ich bin damit einverstanden, dass diese Basis abgedeckt wird.\.cdg$|\.CDG$|\.mp3$|\.MP3$

zipinfo -1 "CB30035-05 - EINFACHER PLAN - Ich würde alles tun.zip" 

  CB30035-05 - Einfacher PlanIch würde alles tun.cdg
  CB30035-05 - Einfacher PlanIch würde alles tun.mp3

entpacken -Z1 "CB30035-05 - EINFACHER PLAN - Ich würde alles tun.zip" 

  CB30035-05 - Einfacher PlanIch würde alles tun.cdg
  CB30035-05 - Einfacher PlanIch würde alles tun.mp3

7za -ba l "CB30035-05 - EINFACHER PLAN - Ich würde alles tun.zip"           

   2003-06-27 14:41:56 .... A 1516512 379652 CB30035-05 - Einfacher PlanIch würde alles tun.cdg
   2003-06-27 14:42:22 .... A 3369876 3112004 CB30035-05 - Einfacher PlanIch würde alles tun.mp3



EDIT 2020120701:


@ G-Man sagt 'Reinstate Monica'

Vielen Dank, dass Sie Ihre Erklärungen so detailliert behandelt haben. Ich weis das zu schätzen. Ich werde Ihre vorgeschlagenen Mods in das Scripting einbeziehen. In Bezug auf

Wenn Sie den Code so geändert haben, dass er .cdg liest$|.CDG$| .mp3$|.MP3$ und das hat meine Ergebnisse nicht verändert “, dann hast du es falsch gemacht ...

Ich bin mir ziemlich sicher, dass ich Ihrem Beispiel genau gefolgt bin. Ich hatte kommentiert, dass ich das getan habe, aber der Backslash wurde aus meiner Bemerkung gestrichen. Ich hatte auch schon das grep "c" implementiert. Aber anscheinend hat die "i" -Option ernsthaft verpasst. Das würde das definitiv aufräumen.

Hier ist der Code wie er jetzt ist ...

#! /bin/bash

prefix="00001_"

mkdir -p ${prefix}{DONE,FIX,BAD} shopt -s nocaseglob for i in *.ZIP; do zip_name="$i"
        pair_exists=$(unzip -Z1 "$i" | grep -Eci -- '\.cdg$|\.mp3$')

        if [ $pair_exists -eq 2 ] then cdg_name=$(unzip -Z1 "$i" | grep -E -- '\.cdg$|\.CDG$') mp3_name=$(unzip -Z1 "$i" | grep -E -- '\.mp3$|\.MP3$') base_name="${zip_name%.*}"
                new_cdg_name="$base_name.cdg" new_mp3_name="$base_name.mp3"

                        printf 'cdg_name = [%s]\n' "$cdg_name" printf 'mp3_name = [%s]\n' "$mp3_name"

                unzip -qq "$i" mv -- "${cdg_name}" "${new_cdg_name}" mv -- "${mp3_name}" "${new_mp3_name}" mv ./"$zip_name" ./${prefix}DONE/ elif [ $pair_exists -gt 2 ]
            then
                echo ""
                echo "NEEDS FIXED: $zip_name" mv ./"$zip_name" ./${prefix}FIX/ elif [ $pair_exists -lt 2 ]
            then
                echo ""
                echo "ARCHIVE IS BAD: $zip_name" mv ./"$zip_name" ./${prefix}BAD/

        else
                echo ""
                echo "HMM"
                echo ""
        fi
    done
exit

Ich habe auch Ihre Änderungen übernommen.

In Bezug auf ein Debug hatte ich wieder "echo" verwendet. Das steht in meinem Testskript ...

echo ""
echo "-----"
echo   $pair_exists
echo   $zip_name echo $cdg_name
echo   $mp3_name echo $new_cdg_name
echo   $new_mp3_name echo $prefix
echo   $log
echo "-----"
echo ""

Es produzierte das gleiche wie Ihr "printf". Ich mag jedoch Ihre ausgefallenen Wege sehr und werde Ihren Stil übernehmen. :) :)

Um Punkt 5 zu beantworten. Ich kam auf diese Idee, als ich 7z.exe verwendete. Eigentlich über eine GUI betrachten. Jetzt werde ich einen Screenshot von dem veröffentlichen, was meine Windows-Box sieht, und wieder werde ich veröffentlichen, was meine Linux-Box produziert.

FENSTER :

LINUX :

Ich habe keine Ahnung, warum das passiert. Nachdem ich mir das eine Weile angesehen habe, denkt ein Teil von mir vielleicht nur ... Ich habe meine Umgebung irgendwie durcheinander gebracht. Ich habe noch nie ein Problem wie dieses gekreuzt und es lässt mich meine Haare ausreißen!

JETZT! Nachdem ich Ihnen all diese Informationen gegeben habe, und vielleicht habe ich Ihnen nicht genug gegeben. Aber ich muss es dir sagen. Nachdem Sie Ihre Änderungen am Code vorgenommen haben, wird das richtige Ergebnis erzielt! Obwohl mein System immer noch das "-" aus den Dateinamen entfernt, erzeugt es das gewünschte Endergebnis. Ich wollte, dass die Dateien den Namen der Zip-Datei annehmen, und genau das macht es jetzt.

Die Änderungen, die ich vorgenommen habe ...

  1. bereinigt die pair_exists mit
    unzip -Z1 "$i" | grep -Eci -- '\.cdg$|\.mp3$'

  2. Bereinigen Sie die Extraktion von cdg und mp3_name und entfernen Sie die awk
    cdg_name=$(unzip -Z1 "$i" | grep -E -- '\.cdg$|\.CDG$')
    mp3_name=$(unzip -Z1 "$i" | grep -E -- '\.mp3$|\.MP3$')

  3. hat den neuen Vorschlag für base_name aufgenommen und das Echo entfernt
    base_name="${zip_name%.*}"
    new_cdg_name="$base_name.cdg"
    new_mp3_name="$base_name.mp3"

  4. fügte die "printf" Debug-Zeilen hinzu (kommentiert sie aus, wenn 150k + Datei ausgeführt wird)
    printf 'cdg_name = [%s]\n' "$cdg_name"
    printf 'mp3_name = [%s]\n' "$mp3_name"

  5. Ich ändere den Dekomprimierer auf Entpacken, um mit dem Toolset konsistent zu bleiben
    unzip -qq "$i"

Ich weiß nicht, wo das Problem behoben wurde, aber ich schätze Ihre Hilfe sehr. @ G-Man sagt 'Reinstate Monica' und hilft mir dabei und gibt einige sehr solide Ratschläge.

Dankeschön!


Antworten

1 G-ManSays'ReinstateMonica' Dec 07 2020 at 21:17
  1. Der Kommentar von steeldriver identifiziert mit ziemlicher Sicherheit einen Teil des Problems. Wenn Sie „den Code zum Lesen geändert haben und dies meine Ergebnisse nicht geändert hat“, haben Sie es falsch gemacht - insbesondere haben Sie es unvollständig gemacht. Ein Teil des Problems liegt im Befehl\.cdg$|\.CDG$|\.mp3$|\.MP3$

    cdg_name=$(unzip -Z1 "$i" | grep -E -- '.cdg|.CDG' | awk '{print substr($0,index($0,$1))}')
    

    was geändert werden muss zu

    cdg_name=$(unzip -Z1 "$i" | grep -E -- '\.cdg$|\.CDG$' | awk '{print substr($0,index($0,$1))}')
    

    weil Übereinstimmungen , und so wird auf die Verkettung beider Namen gesetzt , durch einen Zeilenumbruch getrennt.   Dies geht aus der Fehlermeldung deutlich hervor .cbscdge450-5-0068 - Carpenters ….cdgcdg_namemv

  2. Nur zur Vereinfachung können Sie Änderungen vornehmen

    unzip -Z1 "$i" | grep -E -- '\.cdg$|\.CDG$|\.mp3$|\.MP3$' | wc -l
    

    zu

    unzip -Z1 "$i" | grep -Ec -- '\.cdg$|\.CDG$|\.mp3$|\.MP3$'
    

    (mit der Option c ount von grep) oder sogar

    unzip -Z1 "$i" | grep -Eci -- '\.cdg$|\.mp3$'
    

    (mit der i gnore case Option von grep).

  3. Es gibt kaum einen Grund zu sagen . Tatsächlich neige ich dazu zu sagen, dass es nie einen Grund dafür gibt, aber wahrscheinlich wird jemand einen seltsamen Eckfall identifizieren, bei dem es von Vorteil ist. Speziell,$(echo "something")

    new_cdg_name="$(echo "${zip_name%.*}.cdg")"
    new_mp3_name="$(echo "${zip_name%.*}.mp3")"
    

    kann geändert werden zu

    new_cdg_name="${zip_name%.*}.cdg" new_mp3_name="${zip_name%.*}.mp3"
    

    Ich könnte sogar so weit gehen, sie zu ändern

    base_name="${zip_name%.*}" new_cdg_name="$base_name.cdg"
    new_mp3_name="$base_name.mp3"
    

    PS Genau genommen sind die obigen Anführungszeichen nicht erforderlich, aber es wird empfohlen, sie ständig zu verwenden, es sei denn, Sie haben einen guten Grund, dies nicht zu tun.
    PPS Im falschen Kontext können beispielsweise Änderungen an (dh mehrere Leerzeichen zu einem komprimieren) vorgenommen werden.$(echo "something")Plan  - IPlan - I

  4. Stellen Sie sich vor, Sie sind die Polizei, die versucht, ein Verbrechen aufzuklären, und Sie können nur mit einem Fernglas vor dem Hauptquartier der Kriminellen sitzen. Wäre es nicht viel besser, wenn Sie einen Abhör- oder Informanten bekommen könnten, um zu wissen, was im Inneren des Gebäudes vor sich geht? Das Debuggen ist wie der Versuch, ein Verbrechen aufzuklären - während die externen Informationen (dh die Ausgabe von zipinfound 7za, die separat ausgeführt werden) wichtig sind, um das Problem zu verstehen, hilft es wirklich, die Insiderinformationen zu erhalten. Als routinemäßigen Debugging-Schritt empfehle ich daher, Anweisungen wie hinzuzufügen

    printf 'cdg_name = [%s]\n' "$cdg_name" printf 'mp3_name = [%s]\n' "$mp3_name"
    

    zum Skript. Dies hätte deutlich gemacht, dass cdg_namedie Verkettung der beiden Namen eingestellt wurde, und es könnte Ihnen helfen, herauszufinden, wo I'd Do AnythingÄnderungen vorgenommen wurden I\'d Do Anything.

  5. Genau genommen sollte dies ein Kommentar sein, aber solange ich hier bin: Woher kam die Idee, dass die Namen der darin enthaltenen Mitgliedsdateien CB30035-05 - SIMPLE PLAN - I'D DO ANYTHING.zipwaren

    • CB30035-05 - Simple Plan - I'd Do Anything.cdg und
    • CB30035-05 - Simple Plan - I'd Do Anything.mp3

    Wenn Sie uns keinen Befehl gezeigt haben, der etwas zwischen dem  Planund dem  anzeigt I?

  6. Wie ich oben erwähnt habe, I\'d Do Anythingist das ein Puzzle. Aber haben Sie tatsächlich Beispiele für Probleme im Zusammenhang mit Kommas, Backticks oder Nicht-ASCII-Zeichen (wie 'é', 'Φ', 'Ø', 'θ', '½' oder '∞')?