¿Cómo eliminar una línea específica de un párrafo en AppleScript, manteniendo el formato original del texto?

Tengo una variable de texto de clase textque muestra algo como esto cuando se devuelve:

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

Quiero poder eliminar líneas específicas del texto, sin afectar el resto de la variable.

Por ejemplo: delete {1, 3}para obtener este resultado:

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

El método descrito en esta respuesta tiene un error grave:

"¿Cómo eliminar una línea específica de un párrafo en AppleScript?"

El método vinculado para eliminar líneas en un párrafo en realidad convierte todos los saltos de línea en la variable de texto en retornos. En otras palabras, es imposible ejecutar este código más de una vez en la misma variable.

Por ejemplo, el siguiente código:

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

devoluciones

""

Dado que este método solo funciona correctamente si las líneas de la variable de texto son el producto de a linefeed(como debería), el problema no es que este método no perciba a returncomo una nueva línea (como había afirmado originalmente en esta pregunta). El problema es que este código introduce una returnvariable de texto en primer lugar.


Por lo tanto, quiero una solución que me permita ejecutar la misma variable de texto a través de la solución más de una vez en el mismo AppleScript.

En otras palabras, estoy buscando un método para eliminar una línea específica de un párrafo que no tenga este error y no inserte una returnen ninguna parte del texto.

Con respecto a la información en su edición: el do shell script "sed ..." comando cuando se ejecuta en Terminal con eso varTextregresa con \n(x0A) no \r(x0D) como se supone que debe hacerlo. Incluso el do shell script "sed ..." comando compilado en Script Editor todavía tiene \n(x0A) no \r(x0D), sin embargo, por qué se devuelve con \r(x0D) la intención de lo esperado \n(x0A) es un misterio para mí en este momento. Voy a considerar esto como un error de AppleScript ya que no refleja el comportamiento esperado del mismo cuando se ejecuta en la Terminal. Es por eso que eliminé mi respuesta porque no estaba al tanto del problema.
GrahamMiln Desde que identifiqué el error con la respuesta original que me llevó a publicar la segunda pregunta, ¿es posible fusionar estas dos preguntas? De lo contrario, ¿puede eliminar esta pregunta por completo, ya que @ user3439894 ha proporcionado su respuesta actualizada sobre la segunda pregunta?
No quiero eliminar esta pregunta yo mismo, porque hacerlo resultará en una huelga contra mi cuenta de SE. (Entiendo que el acto de borrar la propia pregunta está penalizado).
En su punto sobre el uso return, ¡por supuesto que estoy de acuerdo! ¡En realidad, no uso y nunca he usado returnpara concatenar cadenas de varias líneas! Es por eso que tuve que editar significativamente el título y el cuerpo de esta pregunta; mi publicación contenía varias declaraciones inexactas. Esta publicación se publicó por primera vez antes de que me diera cuenta del error en su código, que (finalmente me di cuenta) ¡explicaba de dónde returnsvenían todas las variables de mi texto! Originalmente había asumido que yo era, de alguna manera, responsable de la prevalencia de los returnpersonajes, lo cual, ahora sé, no es el caso.
En primer lugar, ¡no era mi código per se el que tenía el error! Es un error en la forma en que el do shell script comando procesa lo que se devuelve desde la línea de comandos , ¡es AppleScript el que no procesa correctamente la salida de los comandos ejecutados dentro del do shell script comando ! Su uso returncomo una concatenación de cadenas de varias líneas fue un problema, ya que vio el contenido de la variable como una línea y lo eliminó porque no sedesperaba finales de línea. De todos modos, mi respuesta actualizada maneja tanto el mal uso de over como el error. x0Ax0Dreturnlinefeed
Sí, obviamente no quise dar a entender que usted personalmente es responsable :). Cuando dije "error en su código", fue una abreviatura de "el error de AppleScript que se manifestó en la solución que proporcionó". Usted escribió: "Su uso de return como una concatenación de cadenas de varias líneas fue un problema". Como dije, entendí completamente mal el problema en cuestión (porque no me di cuenta del error de AppleScript) cuando proporcioné ese ejemplo de usar returnpara concatenar en la publicación original.
Ni una sola vez en toda mi vida he utilizado realmente returnpara concatenar; ese ejemplo existía para resaltar un problema que en realidad no era el problema. Pregunta no relacionada... ¿ha tenido la oportunidad de corroborar mi observación sobre la respuesta de Graham?
De acuerdo, jugué con su código y parece que no funciona como usted desea, incluso cuando reemplaza todo menos el último returncon linefeedo usa el otro método para configurar la variable. Miraré más de cerca mañana cuando haya terminado por la noche. De todos modos, mi respuesta emplea una corrección de errores y puede manejarse returncuando se usa como una constante de carácter de cadena especial de clase de texto o lo que se devuelve del do shell scriptcomando.

Respuestas (3)

De acuerdo, eliminé el original y la primera edición porque editaste tu pregunta original hasta el punto en que es más fácil escribir una nueva respuesta.

Dado que su pregunta original mostraba la siguiente línea de código , como ejemplo de cómo se puede configurar la variable, la incluiré para decir lo siguiente.

Si el varTextha sido establecido por ejemplo:

set varText to (return & "This is sentence 1." & return & "This is sentence 2." & return & "This is sentence 3." & return & "This is sentence 4.")
  • En cuál returnes x0Dvs. el uso más apropiado de linefeed( x0A) en su lugar, en un caso donde la variable son datos y no un mensaje descartable.

O:

set varText to "
This is sentence 1.
This is sentence 2.
This is sentence 3.
This is sentence 4."
  • En el que cada una de estas líneas en realidad termina con un linefeed( x0A) como debería ser en una Mac.

El do shell script comando tiene un error , ya que se convierte x0Adespués x0Dde lo que se devuelve desde la línea de comandos con las x0Aterminaciones esperadas devueltas. Confirmé esto porque si uso lo siguiente:

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"

Luego outfilecontiene terminaciones linefeed( x0A), por lo que se devuelve lo mismo do shell script, pero luego convierte erróneamente las x0Aterminaciones de línea en x0Dterminaciones que luego pueden manejarse de la siguiente manera:

Por lo tanto, para acomodar el error , siempre asegúrese de que el contenido de la variable pasada y devuelta contenga x0Afinales de línea utilizando el siguiente códigohandler de ejemplo .

Lo siguiente asume que varTextya ha sido configurado por cualquiera de los métodos descritos anteriormente.

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)

Luego, podría usar lo siguiente nuevamente para eliminar más líneas de 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)

La siguiente imagen muestra un ejemplo de llamar al do shell script " sed ..." comando dos veces.

imagen de ejemplo de código

Esfera de @rubik, mira la imagen que agregué a mi respuesta.
He probado tu text item delimiters to linefeedsolución. Creo que corrige con éxito el pequeño error pernicioso de AppleScript que hemos identificado. Ahora puedo realizar innumerables do shell script "sed -e...operaciones en la misma variable de texto dentro de la misma ejecución de un script, y las líneas especificadas se eliminan de manera confiable según lo previsto. ¡Gracias por su ayuda!

Ejemplo:

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

Devoluciones:

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

Actualización: como resultado de un descubrimiento mencionado en la Edición: de ¿Cómo eliminar una línea específica de un párrafo basado en "retorno" en AppleScript? , permítanme hacer la siguiente declaración:

NOTA: Desafortunadamente, lo que se devuelve en este caso tiene caracteres de retorno de carro (x0D) en lugar de los caracteres de nueva línea esperados (x0A) y, en mi opinión, ¡es un error!

Es un error porque: el do shell script "sed ..." comando cuando se ejecuta en la Terminal con eso varTextregresa con \n(x0A) no \r(x0D) como se supone que debe hacerlo. Incluso el do shell script "sed ..." comando compilado en Script Editor todavía tiene \n(x0A) no \r(x0D), sin embargo, por qué se devuelve con \r(x0D) la intención de lo esperado \n(x0A) es un misterio para mí en este momento y lo consideraré un AppleScript. error ya que no refleja el comportamiento esperado del mismo cuando se ejecuta en Terminal.

Entonces, para tener en cuenta el error en los resultados del do shell script "sed ..." comando , así es como lo manejaría. Después del do shell script "sed ..." comando, use las siguientes líneas de código :

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

Ahora, lo que se devuelve contiene caracteres de nueva línea (x0A) , ya que debería comenzar si no hubiera este error, no los caracteres de retorno de carro (x0D) .


Nota: cuando se compila, la set newLine to "\n"línea de código se mostrará a continuación:

set newLine to "
"
Si elimino solo una línea, ¿sugiere que incluya el punto y coma? Lo probé en ambos sentidos (con y sin el punto y coma) y parece funcionar bien de cualquier forma, pero solo pregunto por su preferencia.
Esfera de @rubik, el punto y coma solo se necesita como separador cuando se especifica más de un rango, en este caso de uso. ¿Qué línea quieres eliminar?
¿Viste la última parte de mi nueva pregunta? Es imposible ejecutar este método dos veces en la misma variable, lo que debe significar que su método de eliminación de línea altera los caracteres de la nueva línea (x0A) a otra cosa (en el proceso de eliminación de una línea).

Dividamos este script en partes más pequeñas y luego juntémoslo todo en un AppleScript.

Este enfoque está escrito completamente en AppleScript y no requiere herramientas externas. El uso de herramientas externas, como perlo sed, probablemente resulte en soluciones mucho más breves, pero ha mencionado en otras preguntas que desea aprender AppleScript.

1. Dividir con delimitadores

Puede usar el comportamiento de los delimitadores de AppleScript para dividir una cadena . Puede cambiar el delimitador como desee a return, linefeedo incluso caracteres como =:

 -- 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. Lista de filtros

Con la lista devuelta, puede filtrar los elementos no deseados mediante un bucle:

 -- 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 los artículos

La lista filtrada de oraciones se puede volver a combinar usando otro bucle:

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

Totalmente AppleScript

La combinación de estos fragmentos da como resultado el siguiente código:

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

La secuencia de comandos anterior podría reducirse combinando el filtro y los bucles de recombinación. Las he dejado como tareas separadas para demostrar mejor sus roles.

Su estrategia también sufre exactamente el mismo error encontrado en el método original proporcionado por @ user3439894 (el error se describe en la parte "Editar:" de mi publicación). Es decir, si myTextcontiene saltos de línea en lugar de retornos, y usa la línea: set myLines to split(myText, linefeed), su código convertirá cada salto de línea que existe en el texto en un retorno, haciendo imposible que la misma variable de texto se ejecute con éxito a través de su método más de una vez. Esperaba una solución que no posea este efecto secundario problemático; Quiero eliminar líneas de la misma variable más de una vez.
La esfera de @rubik, la respuesta de Graham Miln no sufre el mismo error, ya que no está usando un do shell script comando , que es donde está el error. ¡Está usando returncomo mostraste originalmente en la versión original de esta pregunta! No debe usar para concatenar cadenasreturn de varias líneas , debe usar en su lugar. De hecho, si reemplazó todo sea el último en su respuesta, funcionaría como se esperaba al mantener los finales de línea frente a lo que hace cuando se usa como una constante de carácter de cadena especial de clase. linefeedreturnlinefeedx0Ax0Dreturntext
@ user3439894 Tiene razón en que no es, técnicamente, el "mismo" error. Para ser claros, el método de Graham tiene un error diferente, pero con exactamente el mismo efecto que el error en su do shell scriptmétodo. Esta es la prueba: usando saltos de línea en lugar de retornos en la respuesta de Graham, ¿puede ejecutar una variable de texto específica a través de su método más de una vez en el mismo script con todo funcionando correctamente (por ejemplo, eliminando primero la segunda línea del párrafo y luego eliminando la tercera línea, en dos declaraciones separadas)?