Anzeige:
Ergebnis 1 bis 10 von 10

Thema: Files sortieren und packen

  1. #1
    Registrierter Benutzer
    Registriert seit
    11.08.2009
    Beiträge
    10

    Files sortieren und packen

    Hallo Forum,

    ich habe in einem Verzeichnis sehr viele Dateien mit ähnlichem Namen:

    XXX_FEED.YYYYDDDF.DAY.YYYY_MM_DD.gz
    oder
    ORIG_XXX_FEED.YYYYDDDF.DAY.YYYY_MM_DD.gz

    da sich diese Files sehr stark vermehren und ein "ls" nun schon die Zeit überbrückt die man benötigt um einen Kaffee zu holen, sehe ich Handlungsbedarf.

    Ziel währe es jeweils alle Dateien eines Jahres und Monats in ein separates Verzeichnis zu verschieben, daß am besten auch gleich mit angelegt werden soll, wenn es bereits besteht nicht mehr.

    So wie ich das sehe komme ich hier um "sed" nicht drumherum und bitte daher um Hilfe oder Ideen.

    Vielen Dank im Voraus.
    Gruß
    Xanthariel

  2. #2
    Registrierter Benutzer
    Registriert seit
    20.09.2005
    Beiträge
    61
    Hallo Xanthariel,

    ich würde das mit for-Schleife, mkdir, mv und falls nötig auch mit find, aber sed wäre für mich das falsche Werkzeug.
    Willst Du uns Deinen Lösungsansatz mal posten?

    Gruss zst

  3. #3
    Registrierter Benutzer
    Registriert seit
    20.03.2006
    Beiträge
    180
    Code:
    XXX_FEED.YYYYDDDF.DAY.YYYY_MM_DD.gz
    oder
    ORIG_XXX_FEED.YYYYDDDF.DAY.YYYY_MM_DD.gz
    Unter der Maßgabe, dass die obigen Dateinamen IMMER in vier, durch jeweils einen Punkt getrennte Teile zerfällt, und der dritte Teil IMMER die Form YYYY_MM_DD hat sowie die Dateinamen IMMER auf "*.gz" enden, empfiehlt sich die folgende Vorgehensweise:

    1. Erfassen aller Dateinamen in einem Verzeichnis, ${VERZ}, die auf ".gz" enden.
    2. Herauslösen ihres Basisnamens
    3. Herauslösen der Anteile YYYY, MM und DD aus dem Basisnamen
    4. Verschieben der Dateien in das Zielverzeichnis ${ZIEL} (evtl. auf anderer Partition; Ist dort genügend Platz vorhanden?"

    for i in `find ${VERZ} -name "*.gz"` ; do
    BASENAME=`basename $i`
    TEIL3=`echo ${BASENAME} | awk -F "." '{printf("%s",$3) }'`
    YYYY=`echo ${TEIL3} | awk -F"_" '{ printf("%s",$1) }'`
    MM=`echo ${TEIL3} | awk -F"_" '{ printf("%s",$2) }'`
    DD=`echo ${TEIL3} | awk -F"_" '{ printf("%s",$3) }'`

    mkdir -p ${ZIEL}/${YYYY}/${MM}/${DD}
    mv -i $i ${ZIEL}/${YYYY}/${MM}/${DD}
    done

    Du kannst "${ZIEL}/" weglassen; dann werden die Dateien in das Verzeichnis verschoben, in dem Du dieses Skript aufrufst. Besser wäre eine klare Vorgabe VOR der for-Schleife:
    ZIEL="/abc/def" (oder ähnlich)

    Falls eine tagesgenaue Ablage nicht notwendig ist, lasse "/${DD}" bei "mkdir" und "mv -i" einfach weg.

    Gruss
    Dieter

  4. #4
    Registrierter Benutzer
    Registriert seit
    11.08.2009
    Beiträge
    10
    Hallo Dieter,

    vielen Dank für Deine Mühe.
    Dachte ichs mir doch, daß ich ohne SED oder AWK auf keinen grünen Zweig komme.

    Da ich noch am Beginn meiner Skripting-Karriere stehe

    Was meinst Du mit Basename?
    FEED ???
    Das währe die einzige Konstante.
    Alles andere verändert sich permanent

    Gruß
    Xantharielll

  5. #5
    Registrierter Benutzer
    Registriert seit
    20.03.2006
    Beiträge
    180
    Code:
    Da ich noch am Beginn meiner Skripting-Karriere stehe
    Wir haben alle mal klein angefangen, Herr Kollege Skriptologe!

    Code:
    Was meinst Du mit Basename?
    Jede Datei hat einen Namen und steht irgendwo in einem Verzeichnis. Ein solcher Dateiname ist z.B. /u1/abc/def/Hugo.txt

    "Hugo.txt" ist der Basisname, und /u1/abc/def der Verzeichnisname.
    Hast Du z.B. MYNAME=/u1/abc/def/Hugo.txt gesetzt,
    dann ergibt
    `basename ${MYNAME}` den Basisnamen, also "Hugo.txt", und
    `dirname ${MYNAME}` den Verzeichnisnamen, also "/u1/abc/def"

    Code:
    FEED ???
    Das währe die einzige Konstante.
    Alles andere verändert sich permanent
    Du möchtest aus Gründen der Übersichtlichkeit die Dateien in Verzeichnisse ablegen, die nach Jahr und Monat geordnet sind. Also muss sich das Skript die Jahreszahl und die Monatszahl herauspicken und mit diesen Werten Verzeichnisse anlegen. Das tut mein Skript.
    Falls Du "FEED" mit ins Spiel bringen willst, dann musst Du eben nach "FEED" suchen; ich vermute, die Zeichenkette "XXX" ist ein Platzhalter und kann beliebig lang sein. Mein Skript deckt die Suche nach "FEED" nicht ab. Meines Erachtens ist die Suche nach "FEED" auch gar nicht notwendig, da Du die Dateien geordnet nach Jahr und Monat ablegen willst.

    Lass das Skript einfach mal laufen. Am besten, Du erstellst ein Spielverzeichnis, kopierst händisch ein paar Dateien (unterschiedliches Jahr und Monat) hinein, und lässt Dich mal überraschen, was ein gutes Betriebssystem (ich spreche nicht von einem bunten) leistet.

  6. #6
    Registrierter Benutzer
    Registriert seit
    11.08.2009
    Beiträge
    10
    Das kommt dabei raus.
    Es wird auch kein Verzeichnis mit YYYY_MM angelegt.

    Code:
    awk: syntax error near line 1
    awk: bailing out near line 1
    mv: /app/GB4/dyn/vdps/queues/tk/Feed/Done/VDF_FEED.20092131.Sat.2009_08_01.gz and /app/GB4/dyn/vdps/queues/tk/Feed/Done///VDF_FEED.20092131.Sat.2009_08_01.gz ar
    e identical
    So wie es aussieht setzt er hier das Ausgeschnittene Verzeichnis nicht um.

    Code:
    VERZ=/app/GB4/dyn/vdps/queues/tk/Feed/Done
    ZIEL=/app/GB4/dyn/vdps/queues/tk/Feed/Done
    #
    for i in `find ${VERZ} -name "*VDF_FEED*"` ; do
    BASENAME=`basename $i`
    TEIL3=`echo ${BASENAME} | awk -F "." '{printf("%s",$3) }'`
    YYYY=`echo ${TEIL3} | awk -F"_" '{ printf("%s",$1) }'`
    MM=`echo ${TEIL3} | awk -F"_" '{ printf("%s",$2) }'`
    DD=`echo ${TEIL3} | awk -F"_" '{ printf("%s",$3) }'`
    
    mkdir -p ${ZIEL}/${YYYY}/${MM}
    mv -i $i ${ZIEL}/${YYYY}/${MM}
    done

  7. #7
    Registrierter Benutzer
    Registriert seit
    20.03.2006
    Beiträge
    180
    An meinem Arbeitsplatz habe ich nur Windoze und kann daher das Skript unter Linux nicht testen.

    Folgende Hilfestellungen vorab:

    1. Setze beim AUfruf des SKripts vor seinen Namen die Zeichenkette "sh -x "; dadurch siehst du alles was passiert.

    2. Falls das noch zu wenig Info liefert, füge hinter jeder gesetzten Variablen ein echo auf deren Inhalt ab:
    also z.B. echo ${BASENAME}
    oder echo ${TEIL3}
    Vor allem der Inhalt von ${TEIL3} ist wichtig, da von ihm alle anderen Variableninhalte abhängen.

    Diese Zeilen kannst du dann wieder wegnehmen bzw. auskommentieren, wenn alles prächtig läuft.

    3. Die Fehlermeldung "awk ... bailing" bedeutet, dass irgendein Inpterpunktionszeichen nicht richtig gesetzt ist.

    4. Die Zeile TEIL3=`echo ${BASENAME} | awk -F "." '{printf("%s",$3) }'`
    ändere bitte ab auf:
    TEIL3=`echo ${BASENAME} | awk -F "\." '{printf("%s",$3) }'`
    (hätte ich Linux hier, könnte ich es sofort testen).

    5. Wenn Du ein Verzeichnis YYYY_DD willst, musst du die Zeilen "mkdir ..." und "mv -i" entsprechend ändern. ANstatt "${YYYY}/${MM}" nunmehr "${YYYY}_${MM}"

  8. #8
    Registrierter Benutzer
    Registriert seit
    11.08.2009
    Beiträge
    10
    Ich habe das nun so umgestellt:

    Code:
    VERZ=/app/GB4/dyn/vdps/queues/tk/Feed/Done
    ZIEL=/app/GB4/dyn/vdps/queues/tk/Feed/Done
    #
    for i in `find ${VERZ} -name "*VDF_FEED*"` ; do
    BASENAME=`basename $i`
    TEIL3=`echo ${BASENAME} | awk -F "\." '{printf("%s",$3) }'`
    YYYY=`echo ${TEIL3} | awk -F"_" '{ printf("%s",$1) }'`
    MM=`echo ${TEIL3} | awk -F"_" '{ printf("%s",$2) }'`
    DD=`echo ${TEIL3} | awk -F"_" '{ printf("%s",$3) }'`
    
    mkdir -p ${ZIEL}/${YYYY}_${MM}
    mv -i $i ${ZIEL}/${YYYY}_${MM}
    done
    Das Ergebnis:

    Code:
    svpasta:/export/home/t354884=> sh -x clean_Feed.ksh
    VERZ=/app/GB4/dyn/vdps/queues/tk/Feed/Done
    ZIEL=/app/GB4/dyn/vdps/queues/tk/Feed/Done
    + find /app/GB4/dyn/vdps/queues/tk/Feed/Done -name *VDF_FEED* 
    + basename /app/GB4/dyn/vdps/queues/tk/Feed/Done/_/VDF_FEED.20092202.Sat.2009_08_08.gz 
    BASENAME=VDF_FEED.20092202.Sat.2009_08_08.gz
    + awk -F \. {printf("%s",$3) } 
    + echo VDF_FEED.20092202.Sat.2009_08_08.gz 
    awk: syntax error near line 1
    awk: bailing out near line 1
    TEIL3=
    + awk -F_ { printf("%s",$1) } 
    + echo 
    YYYY=
    + awk -F_ { printf("%s",$2) } 
    + echo 
    MM=
    + awk -F_ { printf("%s",$3) } 
    + echo 
    DD=
    + mkdir -p /app/GB4/dyn/vdps/queues/tk/Feed/Done/_ 
    + mv -i /app/GB4/dyn/vdps/queues/tk/Feed/Done/_/VDF_FEED.20092202.Sat.2009_08_08.gz /app/GB4/dyn/vdps/queues/tk/Feed/Done/_ 
    mv: /app/GB4/dyn/vdps/queues/tk/Feed/Done/_/VDF_FEED.20092202.Sat.2009_08_08.gz and /app/GB4/dyn/vdps/queues/tk/Feed/Done/_/VDF_FEED.20092202.Sat.2009_08_08.gz are identical
    + basename /app/GB4/dyn/vdps/queues/tk/Feed/Done/VDF_FEED.20092131.Sat.2009_08_01.gz 
    BASENAME=VDF_FEED.20092131.Sat.2009_08_01.gz
    + awk -F \. {printf("%s",$3) } 
    + echo VDF_FEED.20092131.Sat.2009_08_01.gz 
    awk: syntax error near line 1
    awk: bailing out near line 1
    TEIL3=
    + echo 
    + awk -F_ { printf("%s",$1) } 
    YYYY=
    + awk -F_ { printf("%s",$2) } 
    + echo 
    MM=
    + awk -F_ { printf("%s",$3) } 
    + echo 
    DD=
    + mkdir -p /app/GB4/dyn/vdps/queues/tk/Feed/Done/_ 
    + mv -i /app/GB4/dyn/vdps/queues/tk/Feed/Done/VDF_FEED.20092131.Sat.2009_08_01.gz /app/GB4/dyn/vdps/queues/tk/Feed/Done/_ 
    + basename /app/GB4/dyn/vdps/queues/tk/Feed/Done/VDF_FEED.20092193.Fri.2009_08_07.gz

  9. #9
    Registrierter Benutzer
    Registriert seit
    20.03.2006
    Beiträge
    180
    Ich bin immer noch in der bunten Windoze-Welt ;-)

    LÖSUNG 1:
    Ersetze die mit "TEIL3=" beginnende Zeile durch:

    TEIL3=`echo ${BASENAME} | awk -F " " 'BEGIN{ x[10] = "";}{ split($0,x,"."); printf("%s",x[4]); }'`


    LÖSUNG 2 (besser):
    Ersetze die mit "TEIL3=" beginnende Zeile durch:

    TEIL3=`echo ${BASENAME} | sed -e 's/\./:/g' | awk -F ":" '{ printf("%s",$4); }'`

    Hinweis:
    In der Zeile "TEIL3=" hätte es rechts von Anfang an heißen müssen "$4" anstatt "$3"; aber das war nicht das eigentliche Problem. Der "awk" mag den Punkt nicht als Feldtrennzeichen.

    Bis nachher ...

  10. #10
    Registrierter Benutzer
    Registriert seit
    20.03.2006
    Beiträge
    180
    Hallo,

    mit der Lösung2 wird TEIL3 korrekt gefüllt und damit auch die Variablen YYYY, MM und DD.

    Der Neugliederung Deiner Dateien sollte nichts mehr im Wege stehen.

    Gruss
    DIeter

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •