Beiträge von AspirinJunkie

    Ich habe eben mal in dem FileWrite Abschnitt den Parameter in '";"' geändert. Hochkommas sind da.


    FileWrite("merged.csv", _Array2CSV($aMerged, Default, '";"'))

    Ne das wird so nicht funktionieren. Zumindest nicht, wenn du Werte mit Zeilenumbrüchen oder Anführungszeichen hast.
    Und in deinem Beispiel war dies so.
    Denn auf die Art hättest du doppelte Anführungszeichen am Wertanfang und das wäre nicht csv-konform.


    Im Grunde ist es nicht viel Code um deinen String wie von dir gewollt zusammenzubauen


    SOLVE-SMART
    Schöne und womöglich bessere Lösung, da einfacher zu verstehen anstatt sich wie bei mir durch alle Spalten einzeln kämpfen zu müssen. :thumbup:

    Eins ist mir noch aufgefallen. Bei einigen Datensätzen ist noch ein Hochkomma " im Merged drin.

    Wie ich sagte, sind Zeilenumbrüchen innerhalb von Einzelwerten in csv nur dann erlaubt, wenn diese Werte in Hochkomma eingeschlossen werden.
    Die Hochkomma müssen also zwangsläufig erscheinen wenn du Werte schreiben willst, welche Zeilenumbrüche enthalten.


    Könnte man denn auch wieder die Texttrennzeichen "" mit in die Merge einfügen?

    Nicht mit der _Array2CSV() bisher. Aktuell habe ich eine umfangreichere UDF in Arbeit, welche auch diese Funktionalitäten hier mit beinhaltet. Dort wird das dann mit drin sein als Switch.

    Musst dir hierfür also was eigenes schreiben, was aber kein großes Problem ist, wenn du das 2D-Array schon vorliegen hast.

    Bei deinen Dateien die du zuletzt hochgeladen hast stimmt etwas noch nicht.
    In der einen Datei ist ein Header - in der anderen nicht.
    Ich habe mich daher mal an die ursprünglichen @Tab-getrennten Daten gehalten und folgendes gebastelt:


    Edit: Und wenn du deinen alten, rein zeilenbasierten Ansatz weiterverfolgen willst, könntest du das Einlesen der Datei folgendermaßen gestalten damit dir die Zeilenumbrüche in den Werten nicht mehr wehtun:

    AutoIt
    #include <Array.au3>
    
    $aCSV1 = StringRegExp(FileRead('results-0.csv'), '(?m)^(?>"(?>[^"]++|"")*+"|[^"\v]*)*+$', 3)
    
    _ArrayDisplay($aCSV1)

    Wenn ich im bereits lauffähigen Script mit "Run" arbeiten möchte, müßte ich also über eine Schleife die Anzahl der ZipAufrufe steuern. Über die Id des Prozesses könnte das bestimmt gehen.

    Sehe ich das richtig ?

    Exakt so!


    Mal ein beispielhafter Grundaufbau hierfür:

    Es gibt eine ziemlich klare Ansage, dass keinerlei Featurerequests oder Bugreports zum Thema Maps zu stellen sind: Autoit documentation


    Und das Thema dot Notation wird schon gleich mal ganz ausgespart in der Dokumentation.


    Ich gebe einem Ticket welches nun ausgerechnet beide Tabuthemen verbindet daher eine Lebenszeit von unter einer Planck-Zeit.


    Edit: Tja schau an - Tickets gibt es dazu also doch. Da scheint die klare Warnung ja doch nicht so klar gewesen zu sein

    Keine Lösung - lediglich ein Workaround:

    AutoIt
    ($mX.method)('AutoIt')


    Nutzt hier jemand die Beta und kann sagen, ob das dort gefixed ist?

    Mir ist keine Beta bekannt, welche neueren Datums wäre als die derzeitige Produktivversion 3.3.16.1
    Es könnten also maximal nicht veröffentlichte Alphas sein wo nur ein paar wenige Zugriff haben.
    water könnte einer dieserjenigen sein.


    Edit: Tja genauso war es dann wohl auch

    Naja script-breaking wäre es ja nicht, da es die Funktion _StringSplit() bisher nicht gibt.
    Ich persönlich würde die auch nicht zusammenmischen wollen, da die Trennung was nun gerade wirklich gemacht wird über den Funktionsnamen eher ersichtlich als über einen Parameter ganz hinten.
    Aber das ist schlicht Geschmackssache.

    Wenn sich jemand aus dem Code eine entsprechende _StringSplit() bauen möchte, kann er das ja machen - der Code ist ja keine Raketentechnik.

    Es geht ja auch ausschließlich um eigenen Code, da wir eh keinen Einfluss auf die AutoIt-Funktionen selbst haben.
    Von daher hat hier jeder alle Freiheiten.

    1. Frage: Wo kommen diese Pfadangaben her? Du musst ja irgendwo definieren welche Ordner bearbeitet werden.

    2.

    Dazu nutze ich einen externen Packer über CLI (Command Line Interface) mit "RunWait"

    Wenn es nur der Aufruf ist - warum dann RunWait und nicht Run()? Mit letzterem hättest du nämlich deine Parallelität.


    3. Wenn hingegen noch hinterher mit AutoIt-Code da an den Ordner weitergearbeitet wird, dann müsstest du dies natürlich entsprechend behandeln.


    Eine Möglichkeit wäre wie von dir vorgeschlagen, dass Skript aufzuteilen und die Unteraufgabe einer Ordnerbehandlung als eigenen Prozess auszuführen.
    Dort musst du dich halt um die Übergabe der Pfadangaben kümmern und da würde ich dir raten den Weg der Aufrufparameter weiterzugehen. Als Austauschspeicher würden auch Dateien gehen oder direkt ein shared-Memory aber das wird dann zu aufwendig und unübersichtlich und da das Subprogramm ja lediglich die Pfade benötigt, kann man die auch ziemlich problemlos einfach dem Programm übergeben.


    Eine weitere Möglichkeit wäre, das Skript in einen Master und einen Slave-Teil einzuteilen.

    Ob das derzeit laufende Skript der Master oder ein Slave ist, kann man z.B. über _Singleton lösen oder über einen Aufrufparameter für die Slave-Teile.
    Dann braucht man nicht 2 verschiedene Skripte.


    Oder du arbeitest ganz normal mit einem einzigen Skript weiter aber rufst die zip.exe halt parallel auf wie oben beschrieben.
    Dann lässt du eine Dauerschleife laufen, die für jede Prozess-ID der Run-Aufrufe prüft ob diese schon abgeschlossen wurden und falls ja, dann entsprechend die Restarbeiten hierzu auszuführen.


    Wenn das alles Aufgaben sind die vom Kommandozeileninterpreter erledigt werden können (Programm aufrufen, Datei kopieren, Ordner löschen klingt für mich so), dann kannst du das auch alles in einen kombinierten Aufruf packen wobei die einzelnen Subbefehle per & verknüpft werden (von AutoIt aufgerufen musst du hierbei an das @ComSpec denken). Auf die Art kannst du von AutoIt per Run mehrere solche Jobs parallel starten.


    Aber wie gesagt: Die Grundfrage für uns wäre eigentlich eher 1.: Wo kommen die Pfadangaben her.

    Im Grunde ist das nix großes - daher keine extra UDF hierfür.
    Worum geht es?: Mit StringRegExp können wir uns die Teile eines Strings zurückgeben, welche einem bestimmten Muster entsprechen. In anderen Sprachen gibt es jedoch noch einen weiteren Ansatz:
    Dort kann man Strings anhand von Trennstrings trennen, deren Muster sich aus einem regulären Ausdruck ergibt.
    Das kann je nach Anwendungsfall einfacher sein als sich ein Muster zu überlegen welches alles andere definiert.


    Im Prinzip funktioniert es wie StringSplit - nur dass man anstatt einem Trennstring eben ein Trenn-Pattern angibt.

    Hierfür dient nun folgende Funktion (kann sein dass soetwas schonmal ein anderer gemacht hat):


    Am besten ist es wohl, wenn du entsprechende Helfertools wie z.B. regex101.com verwendest.

    Ich kenne die js-Funktion split in dem Zusammenhang nicht, vermute aber, dass die die Zeichen haben will an denen gematcht wird.
    Hierfür wäre mein Vorschlag folgendes Pattern: :(?!\/\/)


    Man kann es hingegen auch anders betrachten und anstatt am jeweiligen Match zu splitten einfach alles was nicht Trennzeichen ist matchen.
    Hierfür könnte das Pattern dann so aussehen: (?:[^:]+|:(?=\/\/))+

    Ich hatte keine Ahnung, dass das nur mit den Hex-Zahlen geht. Ich probierte es mit den DEZ zahlen und da kam nur Murks.

    Natürlich geht das auch mit Dezimalzahlen.
    Die hast du aber nicht genommen. Ich habe die Unicode-Codes der Zeichen angegeben.
    Du hingegen hast die ASCII-Codes 124, 47, 45 und 92 verwendet.
    Die dezimalen Unicode-Codes für diese Zeichen, welche so nicht im ASCII-Bereich existieren lauten hingegen 9474 (0x2502), 9585 (0x2571), 9472 (0x2500), 9586 (0x2572)

    Du hast doch im Kommentar schon die richtigen Unicode-Nummern der Zeichen mit angegeben.
    Nur im Code selbst verwendest du hingegen nur die Zeichen aus dem ANSI-Bereich.


    Ändere mal deinen Switch-Teil folgendermaßen und verwende unten ChrW() anstatt Chr():

    Naja du machst ja eine Bedingungsabfrage.
    Willst also die Objekte haben, welche eine bestimmte Eigenschaft besitzen.
    Das geht in einem einzelnen AutoIt-Aufruf nicht.

    Du könntest eine Funktion schreiben in die deine Schleife verpackt wird und du so die Filterung erreichst.

    Oder du nimmst statt einem Array eine Map und verwendest dort als Schlüssel die ID.
    Auf die Art kannst du schnell per ID auf die einzelnen structs zugreifen:

    CBOR ist ein Binärformat, welches beliebig verschachtelte Daten abbilden kann.
    Das Prinzip ist im Grunde das gleiche wie bei JSON.
    Auch dort kann man direkt seine Variablen aus dem Programm nehmen und in dieses Format konvertieren.
    Auf die Art kann man seine Daten außerhalb des Programmes speichern oder mit anderen Programmen austauschen, was umso einfacher ist, da so gut wie alle Programmiersprachen den JSON-Standard verstehen.


    Auch bei CBOR ist das ähnlich, nur mit dem Unterschied, dass CBOR eben kein textbasiertes Format ist, sondern ein Binärformat.
    Das macht es natürlich unmöglich für einen Menschen es direkt zu lesen aber andererseits sind die Ergebnisse in der Regel kleiner als in JSON.


    Nun wie arbeitet man damit? - hier ein Beispiel:

    In diesem Fall belegt unsere AutoIt-Datenstruktur am Ende noch 29 Bytes an Platz.


    Da der Vergleich zu JSON naheliegt - hier noch ein Beispiel (die JSON-UDF wird noch benötigt) um zu schauen wie beide interagieren:


    Changelog:

    2023/02/08
    • Problem bei der Kodierung großer Integerzahlen behoben

    Hinter $file ist dann ein Anführungszeichen zu viel.

    Ausgeben kannst du es so:


    AutoIt
    $file = "C:\Users\user1\Desktop\59116_zert_asa-ssl_b.pfx"
    $pass = 'pass'
    
    $sCommand = "certutil -f -p " & $pass & " -user -importpfx " & $file & " & Pause"
    
    ConsoleWrite($sCommand & @CRLF)
    
    Run($sCommand, "", "", @SW_SHOW)

    Certutil ist auch kein Befehl der cmd.exe sondern ein ausführbares Programm.
    Daher brauchst du dafür auch kein @comspec