AppleScript: come aprire il file di testo e spostare il cursore in una posizione specifica (segnalata da un carattere specifico)?

4

Ho un file .txt salvato sul mio computer. Voglio che la mia applicazione Automator apra il file .txt e quindi sposti la posizione del cursore sulla prima riga vuota del file.

Ad esempio, ho un file .txt intitolato My Fruit Log.txt salvato sul mio computer. Questo è ciò che il contenuto del file .txt può avere:

Quindi, nell'istanza di cui sopra, voglio che il file sia aperto, e quindi il cursore si è spostato sulla seconda riga del file.

Nota: non è necessariamente la seconda riga dalla parte superiore a cui desidero inviare il cursore. A seconda di quale testo è già stato scritto nel file, potrei volere il cursore su una riga inferiore. Ad esempio:

Nel caso precedente, vorrei che il cursore fosse spostato sulla sesta riga.

La posizione in cui voglio che il cursore sia sempre almeno la seconda riga dall'alto, ma potrebbe essere fino alla settima riga dall'alto.

Quindi, il modo più affidabile per articolare dove voglio posizionare il cursore è "alla prima istanza di una riga vuota nel file".

Ho già il codice per aprire il file in TextEdit (preso in prestito dalla risposta superiore di questa domanda di overflow dello stack ):

set Target_Filepath to POSIX file "/Users/Me/Desktop/My Fruit Log.txt"

tell application "Finder" to open Target_Filepath

Ora ho bisogno del codice per spostare il cursore. La posizione predefinita del cursore è la prima riga del file.

    
posta rubik's sphere 24.11.2016 - 02:00
fonte

3 risposte

4

Non so se c'è un modo facile o carino per fare ciò che stai chiedendo. In altre parole, non puoi semplicemente dire qualcosa come open target file and move cursor to first empty line , tuttavia il codice sotto lo farà.

set filePathName to POSIX path of (path to desktop as string) & "My Fruit Log.txt"
set firstEmptyLineNumber to (do shell script "awk '$1 == \"\" {print NR;exit;}' \"" & filePathName & "\"")
do shell script "open -e " & quoted form of filePathName
tell application "TextEdit" to activate
tell application "System Events" to tell process "TextEdit"
    repeat (firstEmptyLineNumber - 1) times
        key code 125 # Down Arrow
    end repeat
end tell

Il codice sopra è codificato per aprire il file di testo in TextEdit, che è ciò che open -e nel secondo
do shell script comando sta facendo ed è codificato in questo modo perché gli eventi di sistema devono sapere dove inviare i tasti freccia giù a. Se vuoi un editor di testo diverso, rimuovi il -e e il comando% em_de% lo aprirà in qualsiasi app l'estensione del file .txt è registrata aperto con. Quindi dovrai anche cambiare:

tell application "System Events" to tell process "TextEdit"

A:

tell application "System Events" to tell front process

E sostituire:

tell application "TextEdit" to activate

Con: open

Nel primo delay 1 comando , do shell script sta ottenendo il numero di riga della prima riga vuota ed esce e questo è quello che viene usato per calcolare quanti < em> freccia giù tasti su awk .

Ho modificato leggermente la mia risposta originale per sbarazzarmi del repeat comando ma volevo aggiungere la mia risposta alla risposta di adc eliminando tutte le roba delay .

set filePathName to POSIX path of (path to desktop as string) & "My Fruit Log.txt"
set firstEmptyLineNumber to (do shell script "awk '$1 == \"\" {print NR;exit;}' \"" & filePathName & "\"")
if firstEmptyLineNumber = "" then set firstEmptyLineNumber to 1 as string
do shell script "open -e " & quoted form of filePathName
tell application "TextEdit" to activate
tell application "System Events" to tell process "TextEdit"
    key code 37 using command down # ⌘L
    keystroke firstEmptyLineNumber
    keystroke return
    key code 123 # Left Arrow - So the line is not highlighted.
end tell

Aggiornamento:

Il codice qui sotto è stato modificato dal codice sopra nella parte superiore della mia risposta, non dalla mia risposta alla risposta di arc sebbene sia applicabile anche lì, per risolvere il problema con TextEdit stai scrivendo due ritorni a capo invece dei normali e previsti feed a due righe per una riga vuota dopo una riga contenente il contenuto o due righe vuote in una riga.

set filePathName to POSIX path of (path to desktop as string) & "My Fruit Log.txt"
set firstEmptyLineNumber to (do shell script "awk '$1 == \"\" {print NR;exit;}' \"" & filePathName & "\"")
if firstEmptyLineNumber is equal to "" then  
    set firstEmptyLineNumber to (do shell script "awk '/\r\r/{print NR+1;exit;}' \"" & filePathName & "\"")
end if
do shell script "open -e " & quoted form of filePathName
tell application "TextEdit" to activate
tell application "System Events" to tell process "TextEdit"
    repeat (firstEmptyLineNumber - 1) times
        key code 125 # Down Arrow
    end repeat
end tell

Nota: anche se il code modificato funziona con il tuo file testfile.txt dal link nel tuo commento, tuttavia personalmente non mi abbono a questa soluzione alternativa e dovresti invece scoprire la causa principale del problema e correggerlo e i tuoi file!

    
risposta data 24.11.2016 - 03:27
fonte
0

Ecco un AppleScript per TextWrangler per passare alla fine del primo paragrafo di un file di testo:

try
    tell application "TextWrangler"
        find "(?=\r^\r|\A)" searching in text of front text window options {search mode:grep, wrap around:false, backwards:false, case sensitive:false} with selecting match
    end tell
end try

Aggiungendo una seconda espressione direttamente dopo (?=\r^\r|\A) ma all'interno delle virgolette si dovrebbe essere in grado di saltare alla riga successiva. Dal momento che non so cosa (?=\r^\r|\A) significa in realtà non posso aiutarti ulteriormente.

    
risposta data 24.11.2016 - 03:20
fonte
0

Probabilmente mi avvicinerei a questo usando qualcosa come Ruby e TextMate- uno script Ruby potrebbe determinare quale linea scegliere (probabilmente con una semplice espressione regolare) e persino aggiungere la data per il giorno successivo, se appropriato. TextMate può essere invocato sulla riga di comando per spostare il cursore su una linea specifica di mate -l 7 , ad esempio.

Detto questo, usando solo AppleScript in TextEdit e awk dalla risposta dell'utente3439894 un modo un po 'più robusto per navigare verso una linea specifica usa Eventi di sistema e la voce di menu "Seleziona linea" (Command + L) di TextEdit.

Ho anche usato una funzione da MacOSXHints perché lo scripting di menu in AppleScript è un enorme problema. Smaltire la funzione menu_click è un esercizio per il lettore.

set filePathName to POSIX path of (path to desktop as string) & "My Fruit Log.txt"
set firstEmptyLineNumber to (do shell script "awk '$1 == \"\" {print NR;exit;}' \"" & filePathName & "\"")
if firstEmptyLineNumber = "" then set firstEmptyLineNumber to 1

do shell script "open -e " & quoted form of filePathName

menu_click({"TextEdit", "Edit", "Find", "Select Line..."})


tell application "System Events"
    keystroke firstEmptyLineNumber
    keystroke return
end tell




-- 'menu_click', by Jacob Rus, September 2006
-- 
-- Accepts a list of form: '{"Finder", "View", "Arrange By", "Date"}'
-- Execute the specified menu item.  In this case, assuming the Finder 
-- is the active application, arranging the frontmost folder by date.

on menu_click(mList)
    local appName, topMenu, r

    -- Validate our input
    if mList's length < 3 then error "Menu list is not long enough"

    -- Set these variables for clarity and brevity later on
    set {appName, topMenu} to (items 1 through 2 of mList)
    set r to (items 3 through (mList's length) of mList)

    -- This overly-long line calls the menu_recurse function with
    -- two arguments: r, and a reference to the top-level menu
    tell application "System Events" to my menu_click_recurse(r, ((process appName)'s ¬
        (menu bar 1)'s (menu bar item topMenu)'s (menu topMenu)))
end menu_click

on menu_click_recurse(mList, parentObject)
    local f, r

    -- 'f' = first item, 'r' = rest of items
    set f to item 1 of mList
    if mList's length > 1 then set r to (items 2 through (mList's length) of mList)

    -- either actually click the menu item, or recurse again
    tell application "System Events"
        if mList's length is 1 then
            click parentObject's menu item f
        else
            my menu_click_recurse(r, (parentObject's (menu item f)'s (menu f)))
        end if
    end tell
end menu_click_recurse
    
risposta data 24.11.2016 - 05:27
fonte

Leggi altre domande sui tag