ich habe in einer errorlog-datei (error.txt) eine liste von dateien in der art:
kann ich diese datei als liste einlesen, mit dem ziel listeneinträge die 3x vokommen herauszufiltern, so dass ich die betreffende datei beim naechsten versuch eines kopierscripts die datei zu bearbeiten auslassen kann?
so in der art:
ab und an haben wir dateileichen im netz die sich weder kopieren noch löschen lassen ...
die Aufgabe ist nicht ganz klar. Ist das Kriterium, die Namen von Dateien zu finden, welche exakt drei Mal vorkommen? Oder soll die Ergebnis-Liste die Dateien aufführen, welche Doubletten oder Tripletten (oder mehr) sind?
Nachstehend schon mal ein erster (kommentierter :-) Versuch, mit welchem in die Liste badList die Namen gesetzt werden, welche in der oldList mehr als einmal vorkommen. --- -- die Datei auswählen set aFile to (choose file) as Unicode text -- den Inhalt als Textkette in eine Variable einlesen set aString to read file aFile -- die 'text item delimiters' bestimmen set AppleScript's text item delimiters to return -- die Textkette in eine Liste verwandeln set oldList to every text item of aString -- die 'text item delimiters' zurücksetzen set AppleScript's text item delimiters to {""} -- eine neue Liste initialisieren set goodList to {} -- die Liste der Leichen initialisieren set badList to {} -- eine Wiederholungsschleife durch die alte Liste repeat with i from 1 to count oldList -- das aktuelle Element der alten Liste set curItem to item i of oldList -- wenn dieses in der neuen Liste vorkommt, dann ... if curItem is in goodList then -- ... wird es an die "schlechte" Liste gehängt ... set end of badList to curItem else -- ... sonst wird es an die "gute" Liste angefügt set end of goodList to curItem end if end repeat -- das Ergebnis wird im Fenster angezeigt badList --- Gruss, Hans
erzeugt, und hat hinter jedem eintrag einen return. wenn die text item delimiters auf return oder "\n" funzt es aber nicht, lediglich wenn die errordatei schon wie im beispiel unten mit kommata getrennt wird¿
ich würde ja in dem shell-script-schnipsel gerne das return gegen ein komma tauschen, aber wie?
da du eh schon in der shell bist, kannst du auch gleich grep zählen lassen, statt eine schleife zu basteln:
try    set fileString to text returned of (display dialog "Eine Begriff eingeben" default answer "") as string endtry
set nTimes to (do shell script "tr '\\r' '\\n' < " & quoted form of "/Users/username/Desktop/error.txt" & " | grep -c " & quoted form of fileString)
display dialog "Die Liste enthält den Begriff \"" & fileString & "\"" & return & return & nTimes & " Mal." with icon 1
der try-block ist allerdings eher unsinnig, da bei einem abbruch der texteingabe deine variable fileString nicht definiert ist und du trotzdem in einen error läufst.
diese variante führt zu einer fehlermeldung, wenn der name nicht in der liste existiert ..¿ ist der gesuchte listeneintrag teil eines anderen eintrages, dann wird dieser mitgezählt. also: grün und grünlich ergäben zwei vorkommen ...
das stimmt. das könnte u.U. ja sogar gewollt sein. das verhalten kann man aber auch einfach abstellen:
set nTimes to (do shell script "tr '\\r' '\\n' < " & quoted form of "/Users/username/Desktop/error.txt" & " | grep -c " & (quoted form of ("^" & fileString & "$")))
und den fehler bei 0 vorkommen kannst du natürlich mit einem try-block und "on error" abfangen.
ich habe mir die berteffenden manpages mal angeschaut.
... und verstehe es natürlich trotzdem nicht ;-) dieser shell-befehl tauscht newline gegen carriage return und schreibt das ergebnis in eine liste¿ wann und warum braucht man die einfachen anführungen?
... ist ein Tunnel, also eine art filter!?
... zählt die vorkommen
... zählt nur die treffer, die als kompletter listeneintrag vorhanden sind ...
danke für deine hilfe:)
gibt es die man-pages auch irgendwo im netz auf deutsch?
hallo -hans- also zunächst mal vorweg: ich bin weit davon entfernt, ein shell-kenner zu sein. es ist aber trotzdem gelegentlich einfacher (naja) und auch schneller, sich mit einer shell-zeile auseinander zu setzen, als viele viele zeilen applescript für die gleiche aktion zu schreiben. und häufig läuft das fertige script dann auch signifikant schneller, als es ein pures applescript täte. dies insbesondere, wenn man finder-aktionen durch entsprechende shell-zeilen ersetzt. es ist allerdings immer vorsicht geboten, da die shell ein scharfes schert ist...
um zum thema zurück zu kommen: wenn wir die scriptzeile mal auf den shell-teil reduzieren: set nTimes to (do shell script "tr '\\r' '\\n' < " & quoted form of "/Users/username/Desktop/error.txt" & " | grep -c " & (quoted form of ("^" & fileString & "$"))) setzt sich der befehl, der an die shell geht, folgendermaßen zusammen:
tr ist der erste befehl, der ausgeführt wird. der befehl dient dem globalen austausch von zeichen. es wird also ein carriage return durch ein newline ersetzt. dann kommt das <. das bestimmt den input für den befehl (also die datei). dann wird der pfad übergeben. dann kommt das |. das ist eine pipe. mit ihr kann man mehrere befehle aneinanderreihen: der output des tr wird also an grep weiter gereicht, statt in der shell ausgegeben zu werden. der ausgabestrom (so nennt man das) des tr dient also dem grep als eingabestrom und wird von diesem verwurstet. das grep -c zählt nun alle zeilen, auf die das nachfolgende suchmuster zutrifft. das ^ steht für zeilenanfang, das $ für zeilenende. es wird also nur "Der Suchstring" gezählt wenn er gleichzeitig am zeilenanfang sowie am zeilenende steht, sprich: die komplette zeile mit dem suchstring gefüllt ist. das verhindert die zählung von teilbegriffen (siehe deinen einwand). ich hoffe, ich konnte helfen.
und die sache mit den einfachen anführungen: für dateinamen-übergaben sollte man IMMER die von mir verwendete "quoted form of"-syntax verwenden, da damit probleme mit speziellen zeichen definitiv vermieden werden. (quoted form of dateipfad) ist nicht das gleiche wie ("'" & dateipfad & "'") !!!!
die single quotes halten generell die shell selbst davon ab, die zeichen, die innerhalb dieser quotes enthalten sind, als befehle zu interpretieren. so dient ja zum beispiel ein einfaches leerzeichen in der shell, um befehle und optionen voneinander zu trennen. wenn man nun einen dateinamen mit einem enthalten leerzeichen ohne quotes an den befehl übergibt, würde die shell das leerzeichen im namen als befehlsende interpretieren und den weiteren teil des dateinamens z.b. versuchen, als optionen oder weitere befehle zu deuten (hoffentlich steht da nicht "rm "). dies wird eben durch die quotes verhindert.
darwins shell ist echt interessant, aber von quark spärlich dokumentiert ... alle befehle von a bis z: http://www.ss64.com/osx/ (der lässt google für sich suchen ... witzisch)