Come eliminare una riga specifica di un paragrafo in AppleScript, mantenendo il formato originale del testo?

-1

Ho una variabile di testo della classe text che mostra qualcosa di simile quando viene restituito:

"
This is sentence 1.
This is sentence 2.
This is sentence 3.
This is sentence 4."

Voglio poter eliminare righe specifiche dal testo, senza influire sul resto della variabile.

Ad esempio: delete {1, 3} per ottenere questo risultato:

"This is sentence 1.
This is sentence 3.
This is sentence 4."

Il metodo descritto in questa risposta ha un bug grave:

< em> "Come eliminare una riga specifica di un paragrafo in AppleScript?"

Il metodo collegato per eliminare le righe in un paragrafo converte effettivamente tutti i linefeed nella variabile text in resi. In altre parole, è impossibile eseguire questo codice più di una volta sulla stessa variabile.

Ad esempio, il seguente codice:

set varText to "
This is sentence 1.
This is sentence 2.
This is sentence 3.
This is sentence 4."
set varText to do shell script "sed -e '1d;3d' <<< " & quoted form of varText
-- Employing the same method on the same variable:
set varText to do shell script "sed -e '1d;3d' <<< " & quoted form of varText
return varText

ritorna

""

Poiché questo metodo funziona correttamente solo se le righe della variabile di testo sono il prodotto di una linefeed (come dovrebbe), il problema è non che questo il metodo non riesce a percepire return come una nuova riga (come avevo originariamente affermato in questa domanda). Il problema è che questo codice introduce un return alla variabile text in primo luogo.

Quindi, voglio una soluzione che mi permetta di eseguire la stessa variabile di testo attraverso la soluzione più di una volta nello stesso AppleScript.

In altre parole, sto cercando un metodo per rimuovere una linea specifica da un paragrafo che non ha questo bug e non inserisce un return in nessuna parte del testo.

    
posta rubik's sphere 16.03.2017 - 05:32
fonte

3 risposte

1

Ok, ho eliminato l'originale e la prima modifica perché hai modificato la tua domanda iniziale al punto in cui è più semplice scrivere una nuova risposta.

Poiché la tua domanda originariamente mostrava la seguente riga di code , come esempio di come la variabile può essere impostata, la includerò per dire quanto segue.

Indica se varText è stato impostato ad esempio:

set varText to (return & "This is sentence 1." & return & "This is sentence 2." & return & "This is sentence 3." & return & "This is sentence 4.")
  • in cui return è x0D rispetto all'uso più corretto di linefeed ( x0A ) invece, nel caso in cui la variabile sia data e non un messaggio usa e getta.

Oppure:

set varText to "
This is sentence 1.
This is sentence 2.
This is sentence 3.
This is sentence 4."
  • in cui ciascuna di queste righe termina effettivamente con un linefeed ( x0A ) come dovrebbe essere su un Mac.

Il comando do shell script ha un bug mentre converte x0A in x0D dopo quello che viene restituito dalla riga di comando che ha le finali% co_de attese restituite. Ho confermato questo perché se io uso il seguente:

set varText to "
This is sentence 1.
This is sentence 2.
This is sentence 3.
This is sentence 4."

set varText to do shell script "sed  -e '1d;3d' <<< " & quoted form of varText & " | tee $HOME/Desktop/outfile"

Quindi x0A contiene outfile ( linefeed ) desinzioni quindi lo stesso viene restituito a x0A ma poi converte erroneamente le estensioni di riga do shell script a x0A desinenze che possono essere gestite come segue:

Quindi, per sistemare il bug , assicurati sempre che il contenuto della variabile passato e restituito contenga x0D terminazioni di riga usando il seguente x0A e example code .

Quanto segue presuppone che handler sia già stato impostato con uno dei metodi descritti sopra.

on ensureLinesEndWith0A(varText)
    set varText to paragraphs of varText
    set oldTID to AppleScript's text item delimiters
    set AppleScript's text item delimiters to linefeed
    set varText to varText as string
    set AppleScript's text item delimiters to oldTID
    return varText
end ensureLinesEndWith0A

set varText to ensureLinesEndWith0A(varText)
set varText to do shell script "sed  -e '1d;3d' <<< " & quoted form of varText
set varText to ensureLinesEndWith0A(varText)

Potresti quindi utilizzare nuovamente quanto segue per eliminare più righe da varText :

set varText to ensureLinesEndWith0A(varText)
set varText to do shell script "sed  -e '1d;3d' <<< " & quoted form of varText
set varText to ensureLinesEndWith0A(varText)

L'immagine qui sotto mostra ed esempio di chiamare il varText comando due volte.

    
risposta data 16.03.2017 - 15:55
fonte
2

Esempio:

set varText to "
This is sentence 1.
This is sentence 2.
This is sentence 3.
This is sentence 4."

set varText to do shell script "sed -e '1d;3d' <<< " & quoted form of varText

Returns:

"This is sentence 1.
This is sentence 3.
This is sentence 4."

Aggiornamento: come risultato di una scoperta menzionata nel Modifica: di Come cancellare una riga specifica di un paragrafo basato su" return "in AppleScript? , lasciare faccio la seguente dichiarazione:

NOTA: Sfortunatamente ciò che viene restituito in questo caso è carriage return (x0D) caratteri invece della nuova linea attesa (x0A) caratteri e secondo me è un bug!

È un bug perché: il do shell script "sed ..." comando quando eseguito in Terminale con quel varText restituisce con \n (x0A) non \r (x0D ) come dovrebbe. Anche il comando di compilazione do shell script "sed ..." comando in Script Editor ha ancora \n (x0A) non \r (x0D) tuttavia perché viene restituito con \r (x0D) inteso del% co_de previsto % (x0A) è un mistero per me al momento e considererò questo un bug di AppleScript dal momento che non rispecchia il comportamento previsto dello stesso quando viene eseguito in Terminal.

Quindi, per tenere conto del bug nei risultati del comando \n , questo è come gestirlo. Dopo il comando do shell script "sed ..." usa le seguenti righe di codice :

set newLine to "\n"
set varText to paragraphs of varText
set oldTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to newLine
set varText to varText as string
set AppleScript's text item delimiters to oldTID

Ora ciò che viene restituito contiene nuova riga (x0A) caratteri come dovrebbe iniziare se non ci fosse questo errore, non ritorno a capo (x0D) caratteri .

Nota: quando compilato, la riga do shell script "sed ..." di codice mostrerà come sotto:

set newLine to "
"
    
risposta data 14.03.2017 - 12:49
fonte
0

Analizziamo questo script in parti più piccole e quindi mettiamo tutto insieme in un unico AppleScript.

Questo approccio è interamente scritto in AppleScript e non richiede strumenti esterni. L'utilizzo di strumenti esterni, come perl o sed , probabilmente si tradurrà in soluzioni molto più brevi ma hai menzionato in altre domande che vogliono imparare AppleScript.

1. Dividi con i delimitatori

Puoi utilizzare il comportamento delimitatori di AppleScript su dividere una stringa . Puoi modificare il delimitatore come desiderato su return , linefeed o anche caratteri come = :

 -- http://macscripter.net/viewtopic.php?id=24473
 to split(someText, delimiter)
     set AppleScript's text item delimiters to delimiter
     set someText to someText's text items
     set AppleScript's text item delimiters to {""} --> restore delimiters to default value
     return someText
 end split

 set myText to (return & "This is sentence 1." & return & "This is sentence 2." & return & "This is sentence 3." & return & "This is sentence 4.")
 set myLines to split(myText, return)

2. Elenco filtri

Con l'elenco restituito, puoi filtrare gli elementi indesiderati utilizzando un ciclo:

 -- http://macscripter.net/viewtopic.php?id=24525
 set indexesToDelete to {1, 4}
 set cleanList to {}

 repeat with i from 1 to count myLines
     if i is not in indexesToDelete then set cleanList's end to myLines's item i
 end repeat

3. Combina gli elementi

L'elenco filtrato di frasi può essere ricombinato usando un altro ciclo:

-- Combine the filtered list into a string
set myResult to ""
repeat with i from 1 to count cleanList
    if myResult is "" then
        set myResult to cleanList's item i
    else
        set myResult to myResult & return & cleanList's item i
    end if
end repeat

Interamente AppleScript

La combinazione di questi snippet genera il seguente codice:

-- Get the text to work with
set myText to (return & "This is sentence 1." & return & "This is sentence 2." & return & "This is sentence 3." & return & "This is sentence 4.")

-- Split the text into lines based on 'return' delimiter
set myLines to split(myText, return)

-- Filter out indexes 1 and 4 using a loop
set indexesToDelete to {1, 4}
set cleanList to {}
repeat with i from 1 to count myLines
    if i is not in indexesToDelete then set cleanList's end to myLines's item i
end repeat

-- Combine the filtered list into a string
set myResult to ""
repeat with i from 1 to count cleanList
    if myResult is "" then
        set myResult to cleanList's item i
    else
        set myResult to myResult & return & cleanList's item i
    end if
end repeat

-- Final string
myResult

to split(someText, delimiter)
    set AppleScript's text item delimiters to delimiter
    set someText to someText's text items
    set AppleScript's text item delimiters to {""} --> restore delimiters to default value
    return someText
end split

Lo script sopra potrebbe essere ridotto combinando il filtro e i circuiti di ricombinazione. Ho lasciato questi come compiti separati per dimostrare meglio i loro ruoli.

    
risposta data 16.03.2017 - 11:00
fonte

Leggi altre domande sui tag