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:
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.
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.
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.
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.
^ $ . [ ] { } - ? * + ( ) | \
. \
precediendolo. Para la prueba de las expresiones regulares crearemos inicialmente un archivo con datos para su búsqueda.
In [1]:
%%bash
ls /bin > test_regexp
ls /usr/bin >> test_regexp
ls /sbin >> test_regexp
ls /usr/sbin >> test_regexp
more test_regexp
Se usará <sec>
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 |
^<sec> |
Indica que la secuencia que precede se ubica al inicio. |
<sec>$ |
Indica que la secuencia precedente se ubica al final. |
[<sec>] |
Indica que los elementos definidos en los corchetes basta con la coincidencia de uno de ellos |
[^<sec>] |
Indica que los elementos definidos en los corchetes porteriores a ^ deben estar ausentes |
[<chr>-<chr>] |
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.
In [2]:
%%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
Para los metacaracteres ERE se tiene el siguiente comportamiento.
Metacaracter | Descripción |
---|---|
sec|sec |
Alternación Coincidencia con alguno de los patrones |
<sec>? |
Elemento precedente opcional (cero o una vez) |
<sec>* |
Elemento precedente opcional (cero o multiples veces) |
<sec>+ |
Elemento precedente con repetición opcional (una o multiples veces) |
<sec>{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
.
In [3]:
%%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
Otras utilidades para habilitar sus expresiones regulares requieren indicación explicita incluso para el soporte POSIX. Ejemplo locate --regex '<regex>'
. En less
y vim
una vez visualizamos el archivo, habilitamos la búsqueda de expresiones regulares con /
.
In [4]:
%%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
In [5]:
!sort prueba3
In [6]:
%%bash
cat prueba3 prueba1 prueba2 prueba3 > repetido
cat repetido
echo ":: uniq sin sort ::"
uniq repetido
echo ":: uniq con sort ::"
sort repetido | uniq
In [7]:
%%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
In [8]:
%%bash
paste horas minutos
In [9]:
%%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
In [10]:
%%bash
echo "EsCrItUrA TeRrIbLe" | tr [:upper:] [:lower:]
Una forma más avanzada es posible con sed
.
In [11]:
%%bash
echo "escritura terrible" | sed 'y/esib/3516/'
echo "escritura terrible" | sed 's/terrible/hermosa/'
Se recomienda la exploración por parte del estudiante de las herramientas de Pandoc y NLTK, como dos ejemplos de bastante interes en el procesamiento de texto y que pueden ser de gran utilidad en su proceso.
A nivel de utilidades linux complementarias, se sugiere la exploración de awk y sed.
Las expresiones regulares son una herramienta poderosa, sin embargo su uso no es recomendable para toda ocasión. Otras estrategias para la manipulación de texto recurren al recorrido de los caracteres para establecer las estructuras mediante la separación y clasificación de elementos mientras son concatenados. Esta resulta ser una estrategia básica bastante útil para muchos casos.
commit
en los cuales fueron agregados en la sección de bibliografía (se debe generar una copia del notebook para este fin de forma automatica). wget
de un sitio estatico. Haga una celda que obtenga una página html con tablas, y extraiga la información de la tabla web a una lista de listas de python de forma automatica, la cual sea convertida posteriormente a una tabla markdown que se visualice adecuadamente.