Fischer-Bayern.de
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen   RegistrierenRegistrieren 
 ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Scripting Additions vs. Shell Skript

 
Neues Thema eröffnen   Neue Antwort erstellen    Fischer-Bayern.de Foren-Übersicht -> AppleScript X
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Snow
Administrator
Administrator


Anmeldedatum: 21.11.2000
Beiträge: 1955
Wohnort: Deiningen

BeitragVerfasst am: 27.08.2005 - 13:58    Titel: Scripting Additions vs. Shell Skript Antworten mit Zitat

Warum gibt es vergleichsweise wenige Scripting Additions unter OS X?
OS X ist ja nun nicht mehr gerade neu - und trotzdem gibt es nur sehr wenige Scripting Additions dafür.

Die Antwort lautet: Sie sind unter OS X nicht nötig, da OS X einen sehr guten Ersatz dafür mitbringt: 'do shell script'

Scripting Additions sind im Prinzip Programme, deren einzige Aufgabe darin besteht, bestimmte Funktionen bereit zu stellen. Diese Funktionen werden jeweils durch verschiedene AppleEvents ausgelöst.

Durch diesen Auslösemechanismus lassen sie sich in Skripten benutzen wie natives AppleScript selbst.

Großer Nachteil: Jedes Skript, das auf Scripting Additions zugreift, setzt voraus, dass die entsprechende Scripting Addition auch auf dem jeweiligen Rechner installiert ist.

Dies ist bei 'do shell script' anders: Denn die Shell steht auf jedem OS X Rechner zur Verfügung.
Da zum Auslösen eines Shellscripts nur der Befehl 'do shell script' zur Verfügung steht, kann man die verschiedenen Funktionen leider nicht so "AppleScript-like" aufrufen, wie es bei Scripting Additions der Fall ist. Man muss die Funktion schon exakt angeben.
Nun sind wir schon beim wohl größten Nachteil der Shell-Skripte: Die Anwendung setzt einen ungleich größeren Lernaufwand voraus als es bei Scripting Additions der Fall ist. Die 'man pages' sind ja auch wohl eher für Leute geeignet, die bereits mit der Materie vertraut sind. - Zum Nachschlagen verschiedener Funktionen und Parameter. - Dem Einsteiger helfen sie oft nicht so schnell weiter.

In der Vergangenheit wurden oft Scripting Additions programmiert, die Funktionen zu Verfügung stellten, die sonst einfach per AppleScript nicht machbar gewesen wären. Stichworte: Textoperationen (siehe z.B. Tanaka's OSAX, Regular Expressions (z.B. Regex Commands).

OS X hat diese Möglichkeiten mit den Shell-Skripten bereits an Bord. Warum sollte sich also ein Programmierer die Arbeit machen, dafür extra noch eine Scripting Addition zu programmieren?

Gemeinsame Nachteile von Scripting Additions und Shell-Skripten:
Der Aufruf kostet Zeit. Dies relativiert sich jedoch schnell, wenn dadurch komplexe Operationen durchgeführt werden.

Ich hatte ja bereits einmal Geschwindigkeitsvergleiche angestellt. Dabei ging es um Suchen/Ersetzen von bestimmten Zeichen in einem Text. Die native AppleScript-Lösung (per text item delimiters) war dort deutlich schneller als eine Shell-Variante mit dem 'sed'-Befehl.

Aber: Dies gilt nur für Operationen, die mit relativ einfachen AppleScript-Mitteln gelöst werden können. Sobald man mehrere Listen und diverse Schleifen einsetzen muss, um ans Ziel zu gelangen, sind Scripting Additions und Shellskripte deutlich schneller.
Bei komplexen Operationen ist also ein Shell-Skript oder eine Skripting Addition der nativen AppleScript-Lösung stets (zeitlich) überlegen, da diese Operationen dort eben durch einen einzigen Befehl ausgeführt werden können.

Wie aus meinen Ausführungen hervor geht, kann man die Shell-Skripte praktisch als Skripting Additions unter OS X betrachten (immer mit dem Vorteil, dass man sich nicht Gedanken darüber zu machen brraucht, ob die "Scripting Addition" am ausführenden Rechner installiert ist - die Shell ist da!)

Es lohnt sich also auf jeden Fall, sich mit Shell-Skripten zu beschäftigen. Die Verbindung zum nativen AppleScript per 'do shell script' stellt ein sehr mächtiges Werkzeug dar, auf das man nicht verzichten sollte. Die Möglichkeiten von AppleScript werden dadurch enorm erweitert, wie es mit einzelnen Scripting Additions nie möglich gewesen wäre.

Nun jedoch zum größten Problem, mit dem sich AppleScripter konfrontiert sehen, wenn sie sich mit Shellskripten befassen möchten:

Man weiß nicht, nach welchem Befehl man überhaupt suchen soll. Wer würde schon erwarten, dass 'sed' irgend etwas mit Text zu tun hat?
Wer die Developer Tools installiert hat, verfügt über das AppleScript-Studio Beispiel "Command Finder". Damit lassen sich Shell-Befehle leicht nach Namen suchen und man kann durch einen Doppelklick auf einen gefundenen Eintrag gleich die entsprechende Manual-Seite aufrufen.
Wenn wir jedoch bei 'sed' bleiben, so heißt es dort als Beschreibung nur "stream editor" - das würde mich immer noch nicht auf den Gedanken bringen, dass dies ein nützliches Tool für Textoperationen ist.

Wer sich also bereits mit Shellskripten auskennt, darf ruhig ein paar Tipps bezüglich Shell-Befehlen an diesen Thread anhängen. Ich werde den Thread anpinnen, damit er stets oben im Forum erscheint.
_________________
Peter
-
Fischer-Bayern.de|Shadetreemicro.com
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen AIM-Name
hweber
•--->
•--->


Anmeldedatum: 01.02.2004
Beiträge: 397

BeitragVerfasst am: 28.08.2005 - 21:34    Titel: Antworten mit Zitat

@snow: Scripting Additions vs. Shell Skript

Ich schließe mich dieser Anregung mit Begeisterung an!

Und möchte zwei kleine Ergänzungen hinzufügen:
Ich kenne die wahren Intentionen der Applescript Programmierer nicht, warum sie diesen wunderbaren Befehl "do shell script", genannt haben. Aber bestimmt ist es kein Zufall, daß er nicht "do shell command" heißt. Hier läßt sich snows Ausführung, warum "es vergleichsweise wenige Scripting Additions unter OSX gibt", vertiefen: "do shell script" kann nicht nur Shell-Befehle ausführen, sondern eben Shell-Scripte. (Und Shell-Scripte sind nichts anderes als gereihte und strukturierte Shell-Befehle in einer "ausführbar" gemachten Textdatei. Weiteres Schnell-Halbwissen will ich hier jetzt so dazu nicht verbreiten.)
Klar sollte werden, daß "do shell script" damit ein Fenster - nein ein riesiges Tor - zu den praktisch unerschöpflichen Möglichkeiten der Welt der Unix-Shell-Scripte öffnet; es gibt nun praktisch nix mehr, was nicht irgendjemand schon irgendwann irgendwo gemacht hat!
Bleibt die Frage, warum dann überhaupt noch AS, wenn es das ALLES schon längst gibt? Ganz einfach: Die Shell kann unsere Lieblings-MAC-Programme nicht steuern wie AS! - von wenigen Ausnahmen abgesehen (z.B. einige FMServer).
"do shell script" ist also für uns AS'er zunächst mehr eine mächtige Schnittstelle zum System; solange wir nicht auf der shell wiederum mit anderen Schnittstellen Unix-Programme Steuern. (Man kann zum Beispiel mit AS-"do shell script" wunderbar eine MySql-DB pflegen)
Allerdings wird Lernbereitschaft als andauernder Wesenszug abgefordert; den ja jeder schon für Applescript aufbringen muß, der mehr machen will, als drei zusammen geklickte Befehle aufzuzeichnen Wink

Und weil dies hier ganz, ganz der Anfang ist, scheue ich mich auch nicht, auf ein mögliches Mißverständnis hinzuweisen (ich weiß, für jeden der "do shell script" benutzt, ist es eine Trivialität): Snows Bemerkung, daß die Shell ja auf jedem OSX schon vorhanden ist, kann leider schnell zu Frustrationen führen. Erstens, hat sich die Standart-Shell und deren Version im Verlaufe von OSX geändert - die Shell ist halt auch nur eine "Anwendung" in der Unix-Welt, wenngleich auch eine sehr, sehr alte. Zweitens benutzt "do shell script" nicht DIE SHELL, die der Anwender aufruft, wenn er das Terminal öffnet (aktuell ist der Standart von 10.3.9 eine bash), sondern eine "System-Shell" sh. Diese verfügt oft über einen eingeschränkten Befehlsumfang und erzeugt demzufolge unerwartete Ergebnisse, wenn ein Befehl im Terminal bereits wunderbar funktioniert hat ..... aber mit "do shell script" TUT ES NICHT.
Entweder, man testet seine Befehle in einer sh (default), oder sagt "do shell script" explizit, daß es bitte auf bash des Terminals arbeiten soll.

Sich durch die Verzweiflungen des Quotierens, des Escapens und der Parameterübergabe zu kämpfen ist immerhin noch systematischer als GUI-Scripting mit AS Smile

Soweit meine Bemerkungen, und nun viel Spaß: Auf das dieser Teil des Forums wachse und gedeihe!

h
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
lensgel
•-->
•-->


Anmeldedatum: 06.08.2005
Beiträge: 28

BeitragVerfasst am: 29.08.2005 - 11:16    Titel: Antworten mit Zitat

Der Grenzbereich zwischen AS und dem Terminal ist ja eins meiner Lieblingsgebiete.

Die Kommunikation zwischen beiden ist wenn man ein paar "Zwänge" akzeptiert auch ganz gut zu machen.

Es empfiehlt sich auf jeden Fall den Befehl (incl. aller Parameter) dedn man absetzen möchte erst mal im Terminal auszuführen.
Wenn man den so ausgetüftelt hat dass er funktioniert muss man sehen wie man die Einzelteile am besten in AS zu einem funktionierenden Befehl zusammensetzt.

Ein kleines Beispiel aus einem alten (Spass-) Script:

Ich möchte aus dem AS heraus eine (Text-) Datei auf dem Desktop anlegen lassen.

Erstes Problem: die Pfade
Der absolute Pfad zum Desktop eines Users lautet normalerweise:
/Users/Username/Desktop
auf meinem eigenen Rechner ist das ganz einfach, wenn ich ein Script herausgebe weiss ich aber den Usernamen desjenigen der das später mal nutzen wird nicht.
Kein Problem, denn unter *nixen kann ich den ganzen Teil bis /Desktop durch
~ (~ stellt das Homeverzeichnis des aktuell angemeldeten Users dar)
substituieren, sieht dann so aus:
~/Desktop
und ist exakt der gleiche Pfad wie:
/Users/Username/Desktop

So kann ich also zumindest den Pfad in eine Variable packen:
set Pfad to "~/Desktop/gothcode.txt"

Ich habe hier jetzt gleich (unsaubererweise) auch den Namen der Datei die erstellt werden soll mit angegeben. In dem Beispielscript weiter unten ist die Trennung zwischen Pfad, Dateiname, und Dateiendung sauberer gelöst.

Was ich mir auch schon in eine Variable packen kann ist der Befehl zum Erstellen der Datei (touch). Also:
set Befehl to "touch "
Zu beachten ist dass im Terminal zwischen Befehl und Pfad ein Leerzeichen steht. Anstatt dass umständlich in den Befehlsstring einzubauen, setze ich das gleich hinter das touch in der Variable Befehl.

Ich habe also (bei diesem simplen Beispiel) schon alles was ich brauche:
set Befehl to "touch "
set Pfad to "~/Desktop/gothcode.txt"

Jetzt muss ich mir den endgültigen Befehl der an den Terminal übergeben wird zusammenbauen, da nach do shell script nur noch der zu übergebende String kommen darf, alles andere würde der Terminal nicht verstehen, es darf also an dieser Stelle nicht mehr "gerechnet" werden.
Der Befehl ist aber leicht zusammengebaut, weil ich schon alles dafür habe. Ich setze also zusammen:
set Exec to Befehl & Pfad
Um auf Nummer sicher zu gehen (was bei Terminalbefehlen nie verkehrt ist, weil man auf dieser Ebene schneller tödliche Befehle absetzt als man manchmal glaubt) lasse ich mir Exec als dialog ausgeben.
Wenn der ausgegebene Text im Dialog wirklich exakt mit der Zeichenkette im Terminal übereinstimmt, dann kann ich AS auch diesen String auf den Terminal loslassen:
do shell script Exec

Wenn ich jetzt in die Datei schreiben will, bin ich mit reinem AS wieder besser beraten:

set thePath to path to desktop
set theFilename to "gothcode.txt"
set theDatei to thePath & theFilename as string
write Gothcode to file theDatei


Jetzt noch ein etwas sinnvolleres Beispiel.
Das Script als Programm gespeichert und in die Toolleiste des Finders platziert, schreibt eine neue Datei ins aktuelle Fenster:

Code:

-- Abfrage Dateiname
set theResult to display dialog "Dateiname" default answer ""
set Dateiname to text returned of theResult

-- Abfrage Dateiendung
set theResult to display dialog "Endung" default answer ".txt"
set Dateiendung to text returned of theResult

-- Bestimmung in welchem Ordner die Datei erstellt werden soll
tell application "Finder"
   
   -- falls unklar wird die Datei auf dem Desktop erstellt
   set theText to POSIX path of ((path to desktop folder) as alias)
   -- Falls ein Fenster offen ist
   if exists front window then
      -- wird der Pfad zu diesem abgefragt
      set theText to POSIX path of (target of front window as alias)
      
   end if
   
end tell
set t to theText

-- der Terminalbefehl
set Befehl to "touch "
-- der Dateiname
set Dname to Dateiname
-- die Dateiendung
set Endung to Dateiendung
-- die gesamte Datei
set Datei to Dname & Endung
-- der Pfad zum Ordner
set Pfad to t
-- Zusammenbau des kompletten Befehls
set Exec to Befehl & Pfad & Datei
-- Übergabe des Befehlsstrings an den Terminal
do shell script Exec


Durch diese Interaktion mit dem Terminal lassen sich natürlich auch wunderbar die Ausgaben eines Terminalbefehls zur weiteren Verwendung durch AS nutzen.
Beispiel:
set t to do shell script "ls ~/Desktop"
t kann nun beliebig "bearbeitet" werden.

Viel Spaß mit AS UND Terminal.

Grüße,
lengsel
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Wolle-77
•--->
•--->


Anmeldedatum: 25.02.2003
Beiträge: 447
Wohnort: Geldern

BeitragVerfasst am: 29.08.2005 - 23:35    Titel: Weitere Tipps Antworten mit Zitat

Hallo Snow,

ich finde es sehr gut, daß Du dieses Thema aufgegriffen hast und auch Deine Zusammenfassung ist (wiedermal, aber lassen wir das Geschleime ;-) gut geworden (speziell der Geschwindigkeitsvergleich; das hatten wir ja vor kurzem) ;-).

Also, ich habe den Reiz der Shell Scripts (also der vielen kleinen Unix-Befehle) vor einigen Monaten entdeckt und erkannt, daß sie sinnvolle Erweiterungen und Ergänzungen zu AppleScript sind.

Da ein do shell script reinen Text zurückgibt, ist das handling denkbar einfach. Ein

do shell script "banner AppleScript" gibt einfach eine riesige "Textwurst" zurück, indem mit dem #-Zeichen das Wort AppleScript gezeichnet ist.

Daß die man-Pages der Befehle an sich meist sehr rudimentär geschrieben sind und die Befehle auch noch fast nicht zu finden sind, macht die ganze Sache so kryptisch und meist sehr schwer zu verstehen.

Nun ist es aber ja nicht so, daß Apple da irgendetwas entwickelt hat (was nicht dokumentiert ist), sondern es gibt das alles ja schon -- teilweise seit Jahrzehnten. Daher ist es auch einfach, an _gute_ Literatur heranzukommen: Ich halte das Buch "Linux in a Nutshell" für sehr gut -- zu 95 % paßt es.

Dann gibt es aber auch im Netz sehr, sehr viele Informationen. Ein Beispiel, recht einfach gehalten (genau richtig), für Mac OS X gibt es hier:

http://www.ruthless.zathras.de/facts/apple/unixbefehle.php

Da sind schon viele Befehle erklärt.

Dann hier auch speziell etwas zu sed:

http://66.249.93.104/search?q=cache:j-K06vbO9jQJ:www.tty1.net/sed-tutorium/html/sed-tutorium.pdf

Und hier wieder Helfer, die aufgeführt sind:

http://www.willemer.de/informatik/unix/utility.htm


Das soll reichen. All diese Seiten habe ich relativ einfach per Suchfunktion gefunden. Aber hier soll ja auch Inhalt gebildet werden. Also:

Ein Beispiel: Die Aufgabe ist, aus einer Datei alle Zeilen zu nehmen, die die Wörter "Mac" und "Apple" enthalten. Das Ergebnis (die -- sehr wahrscheinlich reduzierte -- Zeilenanzahl) soll in eine neue Datei gespeichert werden.

Wer soetwas schon einmal gemacht hat (ich meine nicht von Hand!) weiß, daß das mit AppleScript schon eine ganze Stange Code werden wird.

Bei Verwendung von kleinen Shell-Befehlen als Helfer dagegen wird das ein Einzeiler. Man muß nur die Befehle cat (liest eine Datei) und grep (filtert Zeilen) kennen.

grep ist übrigens mein Lieblingsbefehl.

Der Einfachheit halber nehmen wir an, die Originaldatei heißt test und wir befinden uns bereits im richtigen Ordner:

do shell script "cat test | grep Apple | grep Mac > test_bereinigt.txt"

Das ist alles. Erklärung: Mit cat und der Datei lesen wir die Datei ein. Das |-Zeichen (Alt+7) ist in einer Shell eine sogenannte Pipe – Röhre. Damit leiten wir die Ausgabe eines Befehls in einen neuen Befehl um; wir verketten also die Befehle miteinander. Das schöne ist, auf diese Weise können beliebig viele Befehle miteinander verkettet werden.

Es würde also auch nichts dagegen sprechen zu schreiben:

set t to do shell script "cat test"
set t to do shell script "grep Mac"
set t to do shell script "grep Apple"

Nur, das wäre stümperhaft und langsam, da ja jedesmal AppleScript als Kupplung wieder zutragen kommt und der Datenstrom intern mehrmals ausgetauscht wird.

So, nach cat kommt zweimal grep. Damit filtern wir erstmal alle Zeilen, die Mac enthalten. Dann greppen wir noch einmal die Datei mit dem Filter Apple.

Wir erhalten alle gewünschten Zeilen. Mit dem abschließenden > leiten wir die Ausgabe um in eine Datei; hier test_bereinigt.txt.


Den natürlich in der Praxis benötigten Speicherort bekommen wir übrigens ganz typisch heraus:

set pfad to quoted form of POSIX path of (((path to "docs") & "test") as string)

Hier würde die Datei im Dokumentenordner liegen.

Die Anwendung von sed ist übrigens im Grunde ganz einfach. Es kann (wie alle Befehle unter Unix!) noch viel, viel mehr und es gibt zig Wege, zu einem Ergebnis zu kommen.

sed 's/suche/ersetze/g'

Das ist alles. Ein Such-Tausch-Programm. Das g am Ende steht für global; ansonsten würde nur _das erste_ Vorkommen ersetzt!

Eine Testanwendung von sed als Verständnisbeispiel, in welchem man auch direkt die ungeheure Macht erkennen wird:

Es soll die o-Sprache gebildet werden. Kennt jemand Kalle Blomquist? Also: Jeder Vokal wird mit einem o dazwischen wiederholt. Das Wort 'ist' wird zu 'i sos tot' und 'Blume' wird zu 'Bob lol u mom e'. Es gab bei uns früher Leute, die konnten das fließend aussprechen.

Wer sed nicht kennt, und das mit AppleScript programmieren will, hat eine ganze Stange Arbeit vor sich. Das Ergebnis kann man sich beispielsweise in meiner TextMachine anschauen, die es auf meiner Homepage gibt (Freeware).

Ein Wort -- kein Problem. Aber ein großer Text? Quälend langsam. Ist vergleichbar mit Snows Versuch, das Problem der Ersetzung von allen Bauhaltigen Wörtern zu vermeiden, indem er mehrere Schleifen vorschlug. Da hat Jürgen Venne ja auch schon gezeigt, wie es viel kürzer geht (ist in OS X Snippets).


Also, hier die Vorgehensweise mit sed, der Realität wegen in einem kleinen Projekt mit eingebettet:

set ortext to text returned of (display dialog "Welcher Text soll in die o-Sprache verwandelt werden?" default answer "Macintosh" buttons {"Ok"} default button 1 giving up after 600 with icon 1)

set osprache to do shell script "echo \"" & ortext & "\" | sed 's/[^AEIOUÄÖÜaeiouäöü ]/ &o& /g'"

display dialog "In der O-Sprache heißt der Text" & return & "'" & ortext & "'" & return & return & "'" & osprache & "'" buttons {"Toll"} default button 1 giving up after 600 with icon 1

So, der vom Dialog übergebene Text ortext wird so zur Anwendung und Bearbeitung gebracht:

Mit dem Befehl echo wird einfach text wiederholt. Den nutzen wir, um den Text der Shell zu übergeben:

echo \"" & ortext & "\"

Die zwei Anführungszeichen werden gebraucht, damit der Text maskiert wird. Ansonsten würde bei einem Leer- oder Sonderzeichen der Aufruf einen Fehler schmeißen. Und daher die \.

Dann kommt sed ins Spiel, welches durch die Pipe | den Text von echo übergeben bekommt:

sed 's/[^AEIOUÄÖÜaeiouäöü ]/ &o& /g'

In dieser Fassung ist der Suchbegriff nicht fest, sondern beinhaltet direkt reguläre Audrücke. Hier auch wieder ein Hinweis auf die von Hand programmierte Lösung:

Ihr müßtet einen ersetzen-Aufruf in einer Schleife für jeden Konsonanten wiederholen.

Der reguläre Ausdruck [xx] sorgt dafür, daß jeder Buchstabe in der Klammer gefunden wird. Und das ^ am Anfang sorgt für eine Negation.

Also findet [^e] alle Buchstaben, die NICHT e sind.

In unserem Fall werden also alle Konsonanten und Wortzwischenräume gefunden.

Diese werden dann durch das Suchergebnis (&) ersetzt, einem o und nochmal dem Ergebnis.


(So, das sollte erstmal reichen; mein Text ist jetzt schon zu lang)
_________________
Martin Wolter
--
Apple rocks the planet!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
hweber
•--->
•--->


Anmeldedatum: 01.02.2004
Beiträge: 397

BeitragVerfasst am: 07.09.2005 - 21:04    Titel: mit do shell script FileMaker und Mysql verbinden Antworten mit Zitat

Nicht jeder der Daten aus FileMaker veröffentlichen will, möchte einen Advaced Server kaufen; und nicht jeder möchte in der Datenbank arbeiten, die er mit Instant Web Publishing freigegeben hat.
Ich benutze dafür ein LAMP-System (Linux, Apache, MySql, PHP), welches weniger weniger kostet als eine FileMaker Lizenz, denn das läuft auf fast jedem PC - auch wenn er schon drei, viel Jahre alt ist. Linux, Apache, MySql und PHP installieren sich mit den gängigsten Distributionen fast von allein. Und! - wer mit AS scripted, der findet auch einen Weg zu PHP. Es bleibt, daß man sich mit HTML herumschlagen muß. Aber nicht mehr lange! Auch dafür sind freie Lösungen in Sicht.
Ich spiegele einen Teil meiner Daten, indem ich den Eintrag eines neuen Datensatzes mit einem Script abschließe:

Code:

do shell script "mysql -h 192.168.0.28 -u username -ppassword -D Datenbankname -e 'INSERT INTO Tabellenname VALUES( \"Feldwert1\",\"Feldwert2\",\"Feldwert3\",\"usw\");'"



Ein Update-Script für einen geänderten Datensatz läßt sich genauso leicht zusammenstellen.

Viel Spaß
h
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Kirom
•-->
•-->


Anmeldedatum: 05.04.2005
Beiträge: 93

BeitragVerfasst am: 15.09.2005 - 09:26    Titel: Antworten mit Zitat

Hallo,

Unix, Linux, shell etc.
da schau ich gern hier nach:
http://www.linux-ag.de/linux/LHB/node3.html
_________________
Gruß
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Wolle-77
•--->
•--->


Anmeldedatum: 25.02.2003
Beiträge: 447
Wohnort: Geldern

BeitragVerfasst am: 19.03.2006 - 07:22    Titel: Weitere Besipiele Antworten mit Zitat

Hier ein paar weitere Praxisbeispiel zu regulären Ausdrücken (dem interessantesten Teil):

Mit \( und \) kann man einen (Teil eines) gesuchten String zwischenspeichern, um ihn im zu ersetzenden String (teilweise) mit auszugeben.

Ein Beispiel: Man hat Datumsangaben wie "1.4.2006, 19 Uhr – 2.4.2006, 15 Uhr" oder "28.9.2006 – 11.11.2006" und die Aufgabe ist nun, das ein wenig kürzer zu schreiben, damit es beispielsweise in eine Tabelle paßt.

Mit der Hand: natürlich möglich, schweineviel Arbeit. Mit normalen AppleScript-Mitteln: unglaublich aufwendig. Mit Shell-Befehlen: trickreich, sehr kurz, sehr schnell, aber kompliziert. Daher schrittweise:

Dazu muß man noch eines wissen: Mit \{ und \} gibt man die Menge eines gesuchten Strings an. Es wird geschrieben \{1\} für genau 1, \{7,\} für mindestens 7 und \{7,77\} für mindestens 7, höchstens 77.

Also: Wonach suchen wir? Nach einer oder zwei Zahlen, gefolgt von einem Punkt und nochmal einer oder zwei Zahlen mit einem Punkt (1.4., aber 28.7. oder 28.11.). Diesen Teil wollen wir auch zwischenspeichern, um ihn als Ergebnis auch wieder ausgeben zu können. Wir wollen aber zusätzlich danach noch nach dem 4stelligen Jahr mit einem Komma suchen, welches verworfen werden woll.
Naja, das Komma brauchen wir schon, können es aber auch einfach so im Ergebnis wieder hinzuzufügen. Es dient nur ja nur dazu, daß ein Suchstring möglichst genau beschrieben wird, damit nicht versehentlich eine andere Stelle auch gefunden und ersetzt wird.

Also sieht dieser Teil schon mal so aus: Die Zahlen geben wir (wie bereits beschrieben) in eckigen Klammern als gesuchte Buchstabengruppe an, also [0-9]. Danach die Menge (mindestens 1, höchstens 2) und einen Punkt. Ein Punkt hat in einem regulären Ausdruck allerdings eine Sonderbedeutung (er steht für jedes Zeichen). Damit er als Punkt erkannt wird, muß er ebenfalls mit einem \ maskiert werden.
Obendrein hat ja der \ in AppleScript ebenfalls eine Sonderbedeutung; folglich muß er auch jeweils mit \ maskiert, ergo jeweils doppelt geschrieben werden; ansonsten würde er im Shell-Befehl des do shell scripts nicht ankommen!.

Das alles führt zu der Tatsache, daß ein gesuchter String in regulären Ausdrücken zwar sehr mächtig sein kann, aber mitunter auch sehr abenteuerlich aussieht:

\\([0-9]\\{1,2\\}\\.[0-9]\\{1,2\\}\\.\\)[0-9]\\{4\\},

Ersetzen wollen wir das durch den gesuchten Teilbereich (geht mit \1, also wieder \\1 -- auf diese Art und Weise sind übrigens bis zu 9 Ersetzungsstufen möglich) mit einem Komma:

\\1,

Eingefaßt in einen Befehl sieht das also so aus:
Code:

set t to "28.4.2006, 11 Uhr – 1.11.2006, 19 Uhr"
do shell script "echo '" & t & "' | sed 's/\\([0-9]\\{1,2\\}\\.[0-9]\\{1,2\\}\\.\\)[0-9]\\{4\\},/\\1,/g'"


Ergebnis: "28.4., 11 Uhr – 1.11., 19 Uhr"

Natürlich gibt es – das ist in der Unix-Welt immer so – noch zahlreiche andere Methoden, das so zu erreichen und es wäre in dem Fall sogar über herkömliche AppleScript-Befehle erreichbar, aber nicht, wenn die Daten unstrukturiert und unregelmäßig erfaßt sind. Fazit: reguläre Ausdrücke zu erstellen ist immer eine individuelle Aufgabe für den jeweiligen Ausgangsdatenstrom.

Es folgt nun noch ein weiteres Praxisbeispiel.
_________________
Martin Wolter
--
Apple rocks the planet!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Wolle-77
•--->
•--->


Anmeldedatum: 25.02.2003
Beiträge: 447
Wohnort: Geldern

BeitragVerfasst am: 19.03.2006 - 08:25    Titel: Weiteres zur Zwischenspeicherung: Antworten mit Zitat

Hier ein weiteres praktisches Beispiel zum Umgang mit Zwischenspeicherungen:

Angenommen, wir bekommen eine Liste von Namen, die abgedruckt werden sollen; exportiert aus einer Datenbank mit Komma getrennt. Leider sind die Namen in der Form Nachname, Vorname:

Code:
set t to "Müller, Tom, Maier, Sabine, Kunze, Lisa"


So, als herkömmliche AppleScript-Befehle (nur möglich, wenn die Daten wirklich sauber ankommen) würde das ja so aussehen:

Code:
   set my text item delimiters to ", "
   set t to every text item of t
   set neu to ""
   repeat with i from 1 to (count items of t) - 1 by 2
      set neu to neu & item (i + 1) of t & " "
      set neu to neu & item i of t & ", "
   end repeat
   return neu



Was ist jedoch, wenn die Daten evtl. fehlerhaft erfaßt sind oder eine andere Unregelmäßigkeit auftaucht, die man nicht statisch beschreiben kann? Beispielsweise "Müller,Tom, Maier, Sabine,,,Kunze, Lisa" oder so!?

Dann geht das als regulärer Ausdruck als Einzeiler, der außerdem wesentlich schneller und intelligenter arbeitet (bei 500 Namen mit AppleScript 83 Sekunden zu weniger als 1 Sekunde bei regulärem Ausdruck!); denn wir schaffen es nicht nur, auch leere Datensätze zu erkennen (,,,), sondern können gleichzeitig auch das letzte Komma weglassen, sodaß das Ergebnis nicht "Tom Müller, Sabine Maier, Lisa Kunze, ", sondern "Tom Müller, Sabine Maier, Lisa Kunze" aussieht:

Zusätzlich müssen wir nur wissen, was einmal der * (Stern) und einmal das Hütchen ^ bedeutet:

* bedeutet, daß ein Ausdruck in beliebiger Menge vorkommen darf, also auch keinmal.

^ bedeutet normaler Weise, daß ein String am Anfang einer Zeile vorkommt (siehe oben in diesem Thread). Jedoch in Klammern eingeschlossen [^ ...] bedeutet er, daß die angegebene Gruppe nicht gefunden werden soll.

Wie eben beschreiben wir am Besten mündlich, was wir wollen; nur dann verstehen wir einen regulären Ausdruck gut, das ist sowieso ein guter Tipp:

Wir suchen nach beliebig vielen Zeichen, aber keinem Komma (womit wir den Nachnamen haben) und speichern dieses zwischen, bis zu einem Komma. Danach folgt eine beliebige Menge an Leerzeichen, also auch keines, anschließend suchen wir wieder nach einer beliebigen Anzahl an Zeichen außer einem Komma (speichern dieses zwischen) und es folgt ein Komma in beliebiger Anzahl (beachte: Am Ende steht ja kein Komma! oder es ist evtl. ein leerer Datensatz). Außerdem folgt wieder ein Leerzeichen in beliebiger Menge.

Ersetzen wollen wir das durch den zweiten Teil, gefolgt mit einem Wortzwischenraum, dem ersten Teil, einem Komma und einem Wortzwischenraum. Wir brauchen noch zum Schluß einen zweiten Befehl, der uns das letzte ", " entfernt. In sed, wo ich diese beiden Beispiele hingeschickt habe, kann man beliebig viele Befehle aneinanderhängen mit der Option -e (es ginge auch mit der Pipe |, ist aber zu kompliziert). Also einfach -e /such/ersetz1 -e /such/ersetz2...

Code:
do shell script "echo '" & t & "' | sed -e 's/\\([^,]*\\), *\\([^,]*\\),* */\\2 \\1, /g' -e 's/, $//g'"


Dreimal lesen, dann dürfte es verständlich sein (reguläre Ausdrücke habe ich mir übrigens auch alle alleine beigebracht; AppleScript ist auch nur ein Hobby von mir! Es ist nicht so, daß ich hier von der Kanzel spreche, sondern es soll eine Hilfe sein!).
_________________
Martin Wolter
--
Apple rocks the planet!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Skeeve
•---->
•---->


Anmeldedatum: 20.04.2006
Beiträge: 1068

BeitragVerfasst am: 06.09.2006 - 11:43    Titel: do shell script - Script übersichtlicher gestalten Antworten mit Zitat

Inspiriert durch Wolle-77s posting hab ich festgestellt, wie man scripte, die man für "do shell script" benötigt, übersichtlicher gestalten kann.

Generell geht das mit jeder shell (sh, bash, ksh, csh, tcsh) oder interpreter/compiler (perl, osascript(?)) die ihr script über Standardeingabe einlesen können.

Beispiel:
Wir wollen dieses Script ausführen:
Code:

    cd /etc
    zip /tmp/hosts.zip hosts > /dev/null
    ls -l /tmp/hosts.zip
    rm /tmp/hosts.zip


Das ist sogar noch als Einzeiler lesbar:
Code:
do shell script "cd /etc ; zip /tmp/hosts.zip hosts ; ls -l hosts.zip ; rm hosts.zip"


Wenn das ganze nun etwas länger wird, kann man sich leicht vorstellen, wie kryptisch das werden kann. Also ist hier die Abhilfe.

Grundlage dafür sind die sogenennten Here Documents. Nachzulesen mit:
Code:
man sh
anschließend eintippen /Here Documents

Kurz gesagt: Wenn man in einer shell eingibt
Code:
cat <<'DELIMITER'
text
text
mehr text
DELIMITER

dann wird alles zwischen 'DELIMITER' und DELIMITER behandelt, als wäre es ein Dateiinhalt. Cat gibt es also einfach aus.

Damit läßt sich das ganze nun in ein anderes Programm einspeisen.
Code:

do shell script "cat <<'DELIMITER' | /bin/sh
    cd /etc
    zip /tmp/hosts.zip hosts > /dev/null
    ls -l /tmp/hosts.zip
    rm /tmp/hosts.zip
"

Zu beachten gibt es nur
  • Im Here Document darf kein " auftreten, da damit AppleScripts String beendet würde. \" ist die richtige Notation.
  • Ähnliches gilt für \ da AppleScript das Zeichen nach \ auswertet. Folglich muß man ihn verdoppeln zu \\.
  • DELIMITER darf im Here Document nicht alleine in einer Zeile auftreten! In meiner Antwort auf Wolle-77s Posting habe ich ASCII Character 3 gewählt. Inzwischen habe ich festgestellt: Der DELIMITER kann komplett entfallen. Einfach nur '' (2 Hochkomma) setzen und gut is.
  • bei leerem delimiter ('') sind Leerzeilen zu vermeiden! Statt einer leeren Zeile sollte man dann immer einen Kommentar setzen.

Aber das war ja auch schon bei Einzeilern so...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Wolle-77
•--->
•--->


Anmeldedatum: 25.02.2003
Beiträge: 447
Wohnort: Geldern

BeitragVerfasst am: 30.09.2008 - 15:19    Titel: Der Befehl find Antworten mit Zitat

So, nachdem nun über zwei Jahre hier niemand mehr etwas geschrieben hat und der Befehl find noch gar nicht erwähnt wurde, möchte ich noch einen neuen Befehl ergänzen:

Dieser Befehl heißt find und ist auch aus dem do-shell-script-Kommando heraus anzusprechen.

Seine Ähnlichkeit mit dem Finder ist recht passend, da es genau darum geht, mächtige Dinge zu tun, die mit dem Finder so nicht möglich sind.
Wie bei allen Befehlen Shell-Befehlen wichtig: Immer erst gut nachdenken, bevor man das Script laufen läßt. Ein Apfel+Z gibt es nicht!

Nehmen wir an, wir haben viele verschachtelte (Unter-)Ordner, in denen viele Dateien liegen. Nun wollen wir beispielsweise alle PDF-Dokumente in allen Ordnern auf einen Rutsch bequem in einen zentralen Ordner kopieren. Varianten, die mit dem gleichen Script möglich sind, sind Auflösen aller Unterordnerebenen oder natülich andere Dateiformate.
Auch ist man mit dem find-Befehl sehr flexibel, sodaß man sich nicht aufs Verschieben oder Kopieren beschränken muß. Es wäre beispielsweise auch möglich, alle Wörter aller HTML-Dokumente in vielen Unterordnern zu zählen – und das sehr schnell und leicht mit dem gleichen Einzeiler ...

Code:
set quelle to POSIX path of (choose folder with prompt "Hauptordner auswählen, aus dem die PDFs verschoben werden sollen!")
set ziel to POSIX path of (choose folder with prompt "Zielordner auswählen, in den die PDFs verschoben werden sollen!")
with timeout of 3600 seconds
   do shell script "find \"" & quelle & "\" -name \"*.pdf\" -exec mv -vn \"{}\" \"" & ziel & "\" \\;"
end timeout


Das ist alles. Die Quelle und das Ziel habe ich ausgelagert, damit man sie variabler einfügen kann, das mit dem timeout ist nur Beiwerk. So wie obenstehend nutze ich das Script schon seit ein paar Jahren immer mal wieder, um mehrseitige PDFs aus erzeugten Unterordnern bequem und superschnell sammeln zu können.

Der Befehl setzt sich wie folgt zusammen:

find "Quell/Pfad" (da in AppleScript, muß das " maskiert werden, daher \"" und "\") – find macht sich dort auf die Suche

-name – find ist sehr, sehr mächtig. Hier beschränke ich mich auf die Suche nach Dateinamen. Man könnte aber genausogut auch nach Dateien von heute suchen oder Dateien größer als 1 MB oder Ähnliches ... -name sucht nach einem (Teil eines) Namen(s).

"*.pdf" – sucht nach allen PDF-Dokumenten. Man könnte beispielsweise mit "Kunden_1*.log" nach allen Log-Dateien suchen, die nur von den Kunden mit einer 1 stammen oder so.

-exec – Alle gefundenen Dateien haben wir nun. Schön. Wir wollen aber was damit machen. Und zwar hat der find-Befehl einen eigenen Ausgabemotor, der mit diesem Parameter angestoßen wird.
Was nun danach folgt, gehört streng genommen nicht mehr zum find-Befehl, wird aber von diesem mit ausgeführt, also übernommen.

mv -vn "{}" – das ist der move-Befehl, in diesem Fall werden die Dateien also verschoben. Das -vn heißt einfach verbose (also am Ende wird ein Protokoll mit ausgegeben, kann hilfreich sein und name, also die Dateien werden nicht überschrieben. Noch etwas wichtiges: Das "{}" steht für die Menge, also ist der Platzhalter für die zuvor gefundenen Dateien in einer Liste.

" & ziel & " – Hier ist das Ziel, welches der mv-Befehl benötigt.

\; – Dieses Zeichen ist der Abschluß des find-Befehls, also hier hört der find-Befehl auf.
_________________
Martin Wolter
--
Apple rocks the planet!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Skeeve
•---->
•---->


Anmeldedatum: 20.04.2006
Beiträge: 1068

BeitragVerfasst am: 25.01.2009 - 01:04    Titel: Re: Der Befehl find Antworten mit Zitat

Nette Idee, Wolle, hat aber einen ganz gewaltiges Problem, nämlich genau dann, wenn ein Dateiname - aus welchem Grund auch immer - Anführungszeichen (") enthält.

Aus diesem Grund hat uns Apple "quoted form of" geschenkt.

Der Nachteil: Das hilft uns nicht beim "-exec mv …".

Eine richtige Lösung habe ich allerdings auch (noch) nicht.
_________________
"All problems are solved in slightly less than half an hour" (Chumbawamba, "Hey Hey We're The Junkies")
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Skeeve
•---->
•---->


Anmeldedatum: 20.04.2006
Beiträge: 1068

BeitragVerfasst am: 25.01.2009 - 01:35    Titel: Antworten mit Zitat

Okay. Ich habe eine Lösung:
Code:

set pattern to "*.pdf"
set quelle to POSIX path of (choose folder with prompt "Hauptordner auswählen, aus dem die PDFs verschoben werden sollen!")
set ziel to POSIX path of (choose folder with prompt "Zielordner auswählen, in den die PDFs verschoben werden sollen!")
with timeout of 3600 seconds
   do shell script "find " & (quoted form of quelle) & " -name " & (quoted form of pattern) & " -print0 | xargs -0 -n 1 -I {} mv {} " & (quoted form of ziel)
end timeout


quoted form of sorgt dafür, daß "gefährliche" Zeichen sicher gefiltert werden. Darum auch vor "pattern", damit sicher das * von find und nicht von der shell ausgewertet wird.

-print0 gibt die gefundenen Dateinamen mit einer abschließenden ASCII NULL aus.

xargs liest Dateinamen von Standardeingabe und wendet sie auf andere Programme an. Normalerweise liest xargs Zeile für Zeile. Durch den Parameter

-0 (Null nicht OH) liest es Dateinamen bis zum ASCII NULL. Damit können sicher alle Zeichen in dateinamen verwendet werden.

-n 1 sorgt dafür, daß nicht soviele Dateinamen wie möglich von xargs eingesetzt werden, sondern maximal (in diesem Fall) einer. Man kann hier auch gerne höhere Werte verwenden.

-I {} legt fest, welche Zeichenfolge im Kommando durch den (oder die) Dateinamen ersetzt werden soll.

mv {} " & (quoted form of ziel) ist das auszuführende Kommando.
_________________
"All problems are solved in slightly less than half an hour" (Chumbawamba, "Hey Hey We're The Junkies")
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Wolle-77
•--->
•--->


Anmeldedatum: 25.02.2003
Beiträge: 447
Wohnort: Geldern

BeitragVerfasst am: 06.04.2009 - 11:43    Titel: Antworten mit Zitat

http://www.fischer-bayern.de/phpBB2/viewtopic.php?t=2898

Diesen Thread würde ich als Erweiterung zu diesem Thema anführen wollen, da er zeigt, wie Schleifen in der Shell verwendet werden können.

Es war übrigens mein erster Ausflug in dieses Thema (ich habe den Befehl auf Gut Glück zusammengesetzt…)
_________________
Martin Wolter
--
Apple rocks the planet!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
woodpecker
•--->
•--->


Anmeldedatum: 12.10.2010
Beiträge: 150
Wohnort: Roggentin/Rostock

BeitragVerfasst am: 03.11.2010 - 10:05    Titel: Antworten mit Zitat

Hallo allerseits,

bei komplizierten regulären Ausdrücken wie sie in den UNIX-Kommandos awk, sed, grep, expr u.a. vorkommen fällt man als Anfänger ja meistens auf die Nase, weil man die Wirkung bestimmter Sonderzeichen nicht kennt oder deren Wirkung falsch einschätzt. Um den Umgang mit regulären Ausdrücken zu lernen und ihre Anwendung zu testen, gibt es eine Website, auf der man online testen kann, welche Matches ein bestimmter Ausdruck in einem Text ergibt oder auch wie sich ein Substitutionsvorgang auf den Text auswirkt. Hier kommt der Link:

http://www.gskinner.com/RegExr/

Sehr hilfreich und manchmal auch sehr überraschend!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
TMA
•-->
•-->


Anmeldedatum: 30.11.2005
Beiträge: 53

BeitragVerfasst am: 04.11.2010 - 08:32    Titel: Antworten mit Zitat

Hallo woodpecker,
ja schon sehr nützlich. Schön das es auch eine Desktop Variante davon gibt.

Bisher habe ich immer RegExhibit von Roger Jolly benutzt:
http://homepage.mac.com/roger_jolly/software/

Gruß
TMA
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Fischer-Bayern.de Foren-Übersicht -> AppleScript X Alle Zeiten sind GMT + 2 Stunden
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2002 phpBB Group
Deutsche Übersetzung von phpBB.de


AppleScript für absolute Starter