Forenindex » Programmierung/Entwicklung » AppleScript » liste aus textdatei

liste aus textdatei

Anonym
Beiträge gesamt: 22827

27. Feb 2009, 17:15
Bewertung:

gelesen: 3836

Beitrag als Lesezeichen
ich habe in einer errorlog-datei (error.txt) eine liste von dateien in der art:

Zitat brief
1._FC_Koeln.eps
1._FC_Koeln.eps
1._FC_Koeln.eps
Flags.ai
NikkeK.fh8
rakete.eps


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:
Code
set errorFileList to {die_dateileichen} 
if (d as string) contains "1.FC_Koeln.eps" then
else ...


ab und an haben wir dateileichen im netz die sich weder kopieren noch löschen lassen ...

liste aus textdatei

Hans Haesler
  
Beiträge gesamt: 5826

27. Feb 2009, 20:01
Bewertung:

gelesen: 3835

Beitrag als Lesezeichen
Hallo Hans,

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

liste aus textdatei

Anonym
Beiträge gesamt: 22827

28. Feb 2009, 16:24
Bewertung:

gelesen: 3835

Beitrag als Lesezeichen
hi,
die errordatei wird mit:
Code
do shell script "echo " & quoted form of (origfile) & " >> " & quoted form of "/Users/hans/Desktop/ErrorLog.txt" 

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?

in soweit funktioniert dieses beispiel:

Code
--  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 ", "
-- 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

try
    set fileString to text returned of ¬
        (display dialog "Eine Begriff eingeben" default answer "") as string
end try


set nTimes to 0
if badList contains fileString then
    repeat with i from 1 to count badList
        if item i of badList is fileString then
            set nTimes to nTimes + 1
        end if
    end repeat
end if

if nTimes > 3 then
    display dialog "Die Datei" & fileString ¬
        & " konnte in " & nTimes & " Versuchen nicht kopiert werden und wird nicht weiter bearbeitet." buttons "OK" default button 1 with icon 1
else
    display dialog "Die Liste enthält den Begriff " & fileString ¬
        & ": " & return & return & nTimes & " Mal." buttons "OK" default button 1 with icon 1
end if

liste aus textdatei

Anonym
Beiträge gesamt: 22827

1. Mär 2009, 09:05
Bewertung:

gelesen: 3835

Beitrag als Lesezeichen
set liste to paragraphs of (do shell script "tr '\\r' '\\n' < " & quoted form of "/Users/hans/Desktop/ErrorLog.txt")

liste aus textdatei

Anonym
Beiträge gesamt: 22827

1. Mär 2009, 10:21
Bewertung:

gelesen: 3835

Beitrag als Lesezeichen
super! danke :)
Code
set liste to paragraphs of (do shell script "tr '\\r' '\\n' < " & quoted form of "/Users/hans/Desktop/error-.txt") 


try
    set fileString to text returned of ¬
        (display dialog "Eine Begriff eingeben" default answer "") as string
end try

set nTimes to 0
if liste contains fileString then
    repeat with i from 1 to count liste
        if item i of liste is fileString then
            set nTimes to nTimes + 1
        end if
    end repeat
end if

display dialog "Die Liste enthält den Begriff " & fileString ¬
    & ": " & return & return & nTimes & " Mal." buttons "OK" default button 1 with icon 1

liste aus textdatei

Anonym
Beiträge gesamt: 22827

1. Mär 2009, 11:54
Bewertung:

gelesen: 3835

Beitrag als Lesezeichen
da du eh schon in der shell bist, kannst du auch gleich grep zählen lassen, statt eine schleife zu basteln:

try
&#160;&#160;&#160;set fileString to text returned of (display dialog "Eine Begriff eingeben" default answer "") as string
end try

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.

liste aus textdatei

Anonym
Beiträge gesamt: 22827

1. Mär 2009, 17:47
Bewertung:

gelesen: 3835

Beitrag als Lesezeichen
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 ...

gruss hans

liste aus textdatei

Anonym
Beiträge gesamt: 22827

2. Mär 2009, 18:29
Bewertung:

gelesen: 3835

Beitrag als Lesezeichen
Zitat von author="-hans-" date="1235926061" 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.

liste aus textdatei

Anonym
Beiträge gesamt: 22827

4. Mär 2009, 07:39
Bewertung:

gelesen: 3835

Beitrag als Lesezeichen
hi holgi,

ich habe mir die berteffenden manpages mal angeschaut.

Code
tr — translate characters 
"tr [ ?Ccsu] string1 string2 '\character \r <carriage return>'  '\character\n <newline>' <" "file"


... 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?

Code
| 

... ist ein Tunnel, also eine art filter!?

Code
gre -c 

... zählt die vorkommen

Code
The caret ˆ and the dollar sign $ are metacharacters that respectively match the empty string at the beginning and end of a line. 

... 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?

liste aus textdatei

Anonym
Beiträge gesamt: 22827

4. Mär 2009, 17:55
Bewertung:

gelesen: 3835

Beitrag als Lesezeichen
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:
Code
tr '\r' '\n' < '/pfad/zur/datei.txt' | grep -c '^Der Suchstring$' 

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.

liste aus textdatei

Anonym
Beiträge gesamt: 22827

6. Mär 2009, 07:07
Bewertung:

gelesen: 3835

Beitrag als Lesezeichen
thx :) gut erklärt!

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)