%%bash
ls /bin > test_regexp
ls /usr/bin >> test_regexp
ls /sbin >> test_regexp
ls /usr/sbin >> test_regexp
more test_regexp

"""
Explanation: El procesamiento de texto refiere a la creación y manipulación de texto en formato electronico de manera automatizada, entendiendo el texto no solo como el conjunto de caracteres alfanuméricos sino como el conjunto de cualquier caracter codificado.  
Linux viene acompañado por defecto con un extenso grupo de utilidades para el procesamiento de texto (debido a la fuerte dependencia de archivos de texto para su configuración). Lenguajes como python vienen con modulos de procesamiento de texto básicos incluidos en su núcleo.  
Acciones comprendidas como procesamiento de texto son:  

Búsqueda de texto.  
Reemplazo de texto.  
Filtrado de texto.  
Generación de texto.  
Formateo de texto.  

Nos enfocaremos en lo básico de las utilidades de linux, y se invita al estudiante a realizar la exploración del modulo de python.  
Codificación de caracteres
ASCII
Corresponde a la codificación estandar definida para la representación de caracteres, basada en el uso de 7 bits inicialmente y luego presentada en versión extendida a 8 bits (ISO 8859, ampliamente extendido el 8859-1) para la inclusión de caracteres adicionales de lenguas diferentes al inglés.  
A continuación se presenta una imagen con la codificación asociada al ISO 8859-1.  

UTF8
Posee compatibilidad con el código ASCII y usa representación de hasta cuatro códigos de 8 bits (ASCII extendido es un código de 8 bits). Esta ampliación permite el soporte de una gran diversidad de caracteres sin la necesidad de una indicación particular para su soporta, sin embargo esto requiere un mayor consumo de memoria en algunos lenguajes o presentar problemas de compatibilidad con codificaciones especificas anteriores. Actualmente su uso se ha generalizado superando por mucho a la codificación ASCII.  
Expresiones regulares
El primer acercamiento necesario para el procesamiento de texto se relaciona con las expresiones regulares, que corresponden a secuencias de caracteres que definen un patrón de búsqueda. Lo primero para entender este acercamiento es distinguir entre metacaracteres y caracteres literales.  

Metacaracteres: Son caracteres especiales dentro del minilenguaje especificado en las expresiones regulares usados para definir secuencias de patrones: ^ $ . [ ] { } - ? * + ( ) | \.  
Literales: Son caracteres que se interpretan tal cual son (todos los demás caracteres que no son metacaracteres). Si se desea usar un metacaracter como elemento exacto de coincidencia es necesario usar el caracter de escape \ precediendolo.  

Para la prueba de las expresiones regulares crearemos inicialmente un archivo con datos para su búsqueda.
End of explanation
"""


%%bash
echo ":: non-meta <sec> ::"
grep 'zip' test_regexp
echo ":: meta .<sec> ::"
grep '.zip' test_regexp
echo ":: meta ^<sec> ::"
grep '^zip' test_regexp
echo ":: meta <sec>$ ::"
grep 'zip$' test_regexp
echo ":: meta ^<sec>$ ::"
grep '^zip$' test_regexp
echo ":: meta [<sec>] ::"
grep '[bg]zip' test_regexp
echo ":: meta [^<sec>] ::"
grep '[^bg]zip' test_regexp
echo ":: meta [<chr>-<chr>] ::"
grep '^[A-Z][a-z]' test_regexp
echo ":: meta [[:<class>:]] ::"
grep '^[[:upper:]][[:lower:]]' test_regexp

"""
Explanation: Uso de metacaracteres
Se usará &lt;sec&gt; para indicar una secuencia arbitraria, la cual puede ser compuesta de caracteres literales o 
metacaracteres.  
Las expresiones regulares se dividen en un conjunto BRE (Basic Regular Expression) y ERE (Extended Regular Expression) acorde al soporte definido de los metacaracteres. El primero es soportado acorde al estandar POSIX y se ilustra en el siguiente cuadro.  
| Metacaracter | Descripción |
|:---:|:---:|
| . | Permite la sustitución por cualquier caracter |
| ^&lt;sec&gt; | Indica que la secuencia que precede se ubica al inicio. |
| &lt;sec&gt;$ | Indica que la secuencia precedente se ubica al final. |
| [&lt;sec&gt;] | Indica que los elementos definidos en los corchetes basta con la coincidencia de uno de ellos |
| [^&lt;sec&gt;] | Indica que los elementos definidos en los corchetes porteriores a ^ deben estar ausentes |
| [&lt;chr&gt;-&lt;chr&gt;] | Siendo los caracteres pertenecientes a un subconjunto de caracteres (clase), representa a todos los caracteres contenidos entre ellos |  
En el estandar POSIX se definen un conjunto de clases para simplificar los rangos cuando se usa todo el subconjunto, y es supremamente conveniente su uso para expresiones que requieren rangos donde se difiere del orden diccionario (principalmente por motivos de codificación acorde al soporte de algunas aplicaciones para las expresiones regulares).  
  
Dado que corresponden a rangos, estos deben estar a su vez en medio de otros corchetes.
End of explanation
"""


%%bash
echo ":: meta <sec>|<sec> ::"
grep -E '^2|.zip$' test_regexp
echo ":: meta <sec>? ::"
grep -E '^[a-z]?zip.' test_regexp
echo ":: meta <sec>* ::"
grep -E '^[a-z]*zip.' test_regexp
echo ":: meta <sec>+ ::"
grep -E '^[a-z]+zip.' test_regexp
echo ":: meta <sec>{n,m} ::"
grep -E '^[a-z]{1,3}zip.' test_regexp

"""
Explanation: Para los metacaracteres ERE se tiene el siguiente comportamiento.  
| Metacaracter | Descripción |
|:---:|:---:|
|<code>sec&#124;sec</code>| Alternación Coincidencia con alguno de los patrones |
|&lt;sec&gt;?| Elemento precedente opcional (cero o una vez) |
|&lt;sec&gt;*| Elemento precedente opcional (cero o multiples veces) |
|&lt;sec&gt;+| Elemento precedente con repetición opcional (una o multiples veces) |
| &lt;sec&gt;{n,m} | Coincidencia del precedente mínimo $n$ veces y máximo $m$ veces. Si se usa uno de los dos con la presencia de la , aplica como solo mínimo o máximo según corresponda, y si es uno solo sin la , es las coincidencias exactas |
Para multiples aplicaciones el soporte de ERE debe indicarse de forma explicita, así por ejemplo para la utilidad con la cual hemos ejemplificado, debe usarse grep -E, siendo el argumento -E la indicación del soporte extendido. Igualmente hay utilidades con el soporte incluido, en este caso la alternativa es egrep.
End of explanation
"""


%%bash
printf "hola\nesto\nes\nuna\nprueba.\n" > prueba1
a=1
echo $a > prueba2
while [ $a -lt 5 ]; do
    let a=a+1
    echo $a >> prueba2
done
cat prueba1 prueba2 > prueba3
more prueba3

"""
Explanation: Otras utilidades para habilitar sus expresiones regulares requieren indicación explicita incluso para el soporte POSIX. Ejemplo locate --regex '&lt;regex&gt;'. En less y vim una vez visualizamos el archivo, habilitamos la búsqueda de expresiones regulares con /.  
Manipulación de texto
Concatenación de archivos
Para la concatenación de archivos en linux podemos usar la utilidad cat. Permite la unión de archivos y redirige su unión a la salida estandar.
End of explanation
"""


!sort prueba3

"""
Explanation: Ordenamiento
Es posible ordenar lineas de archivos con los valores definidos en ASCII con la instrucción sort.
End of explanation
"""


%%bash
cat prueba3 prueba1 prueba2 prueba3 > repetido
cat repetido
echo ":: uniq sin sort ::"
uniq repetido
echo ":: uniq con sort ::"
sort repetido | uniq

"""
Explanation: Unicidad
Es posible remover los elementos repetidos de un conjunto con utilidades de linux. Para esto, primero debe ordenarse la lista de elemento (sort) y aplicar uniq.
End of explanation
"""


%%bash
ls -oh
ls -oh | grep -Ev '[[:alpha:]]+ [[:alnum:]]+\.ipynb|total' | grep -Ev '[a-z]{3}  ' > cortar
echo ":: archivo cortar seleccionando lineas ::"
cat cortar
echo ":: Horas enteras de los archivos ::"
cut -d " " -f 7 cortar | cut -c 1-2 > horas
cut -d " " -f 7 cortar | cut -c 4-5 > minutos
echo ":: Horas ::"
cat horas
echo ":: Minutos ::"
cat minutos

"""
Explanation: Cortar
Para extraer secciones especificas de lineas de los archivos usamos la instrucción cut.
End of explanation
"""


%%bash
paste horas minutos

"""
Explanation: Pegado
Para pegar columnas usamos la instrucción paste.
End of explanation
"""


%%bash
printf "a\nb\nf\nh" > ordenado1
printf "a\nc\nd\ng\nh" > ordenado2
echo ":: comm ::"
comm ordenado1 ordenado2
echo ":: diff ::"
diff ordenado1 ordenado2
echo ":: patch ::"
diff -Naur ordenado1 ordenado2 > diferencia
cat diferencia
patch < diferencia
cat ordenado1

"""
Explanation: Comparación de archivos
Es posible comparar archivos con las instrucciones comm y diff. La primera requiere que los archivos sean ordenados. Usando la diferencia de los archivos es posible generar la actualización del archivo base con patch.
End of explanation
"""


%%bash
echo "EsCrItUrA TeRrIbLe" | tr [:upper:] [:lower:]

"""
Explanation: Edición
Es posible hacer "traducciones" con la consola con la instrucción tr. Esto corresponde a substituciones basadas en expresiones regulares.
End of explanation
"""


%%bash
echo "escritura terrible" | sed 'y/esib/3516/'
echo "escritura terrible" | sed 's/terrible/hermosa/'

"""
Explanation: Una forma más avanzada es posible con sed.
End of explanation
"""


