domingo, 21 de octubre de 2012

[Script] Buscador de texto en archivos

Buenas, hoy os traigo algo que tenía ganas de hacer hace mucho tiempo, se trata de un programa (bueno, en este caso es un script) cuya función es buscar cadenas de caracteres (ya sean letras o palabras) dentro de varios archivos de texto plano.

Resumiendo, tu le das dos argumentos al script, la carpeta en la que quieres buscar y la cadena de caracteres que quieres buscar, y el programa se encarga de buscar dicha cadena de caracteres dentro de todos los archivos que hay en la carpeta que le has indicado.

Esta idea me surgió hace muchísimo tiempo, cuando me pasaba en varias ocasiones que tenía una serie de archivos (por lo general eran archivos de código fuente) y no recordaba en que archivo en concreto estaba la información que buscaba, lo cual me obligaba a abrir todos los archivos y realizar una búsqueda individual en cada uno de ellos.

En realidad la idea original la tenia pensado realizar en C, pero por unas cosas y otras, nunca llegué a realizarla. Este script hace uso de 4 programas: cat, wc, grep y test. Los 4 vienen por defecto en todos los linux, así que no tendréis que instalar nada adicional.

Bueno, hablemos de problemas. El script tiene un par de problemas, el primero es el tiempo de ejecución, si en la carpeta que indicáis solo hay archivos de texto plano pues no hay mucho problema, el script debería de ejecutarse en un par de segundos, pero si la carpeta contiene otros archivos de gran tamaño ademas de los de texto plano pues la ejecución puede ser bastante larga, lo he probado con una carpeta que contenía algunos archivos de varios GiB y ha tardado varios minutos en ejecutarse, pero bueno, en condiciones normales con archivos no muy pesados no debería de presentar problemas. El segundo problema es que el programa no es recursivo, esto quiere decir que si dentro de la carpeta que indicáis para la búsqueda existe otra carpeta pues el script no entrara en esta nueva carpeta, solo examinara la carpeta que le habéis indicado.

Si algún día llego a realizar la versión en C del programa, probablemente pueda solucionar estos problemas.

A continuación os dejo el código del script:


#!/bin/bash

if test -z $2
then

        echo
        echo "ERROR !!! Faltan argumentos."
        echo
        echo "Modo de uso: $0 <Directorio> <Cadena de caracteres a buscar>"
        echo


else

max=`ls $1 | wc -l`

for ((i=1; i<=$max; i++))
do

cat "$1/`ls $1 | head -n $i | tail -n 1`" 2> /dev/null\
        | grep -n -i $2 > /dev/null

if test $? -eq 0

then

        echo

        echo ----------------

        echo

        ls $1 | head -n $i | tail -n 1

        echo

        cat "$1/`ls $1 | head -n $i | tail -n 1`" 2> /dev/null\
                | grep -n -i $2

fi

done

fi

echo
echo ----------------
echo




Para guardar el script lo guardáis como un archivo de texto plano y le dais permisos de ejecución, después si queréis, podéis ponerlo en la carpeta /usr/bin/ para poder ejecutarlo desde cualquiera carpeta aunque el script no esté en ella.

Bien, el script toma dos parámetros que son de uso obligado, el primer parámetro es la carpeta donde queréis realizar la búsqueda, y el segundo parámetro es la cadena de caracteres a buscar. De manera que un ejemplo podria ser el siguiente (yo le he llamado bsc al script, pero podéis llamarle como queráis):

./bsc Documentos/ valencia

con este comando el script buscaria en la carpeta "Documentos" todos los archivos que contengan la palabra "valencia"

ACLARACIÓN: si tenéis el script en /usr/bin/ no hace falta poner el "./" inicial para ejecutar el script, ademas el script acepta rutas relativas a vuestra posición actual en el shell, osea que en el caso anterior puedo poner simplemente como carpeta "Documentos" en vez de /home/usuario/Documentos/ ya que en ese momento me encuentro en la carpeta usuario.

La salida que produce el script tiene el siguiente formato: cada archivo en el que encuentra una coincidencia lo muestra entre una serie de lineas salteadas como esta "----------------", después la primera linea que muestra es el nombre del archivo, y las lineas siguientes son las lineas del archivo en las que hay coincidencia, mostrando al comienzo de la linea el numero de linea en la que se encuentra.

Ejemplo:



Como podemos ver en este ejemplo, le hemos dicho al programa que busque en los archivos de la carpeta "test" la cadena "prueba" y en este caso se nos muestra un único resultado, el cual ha sido encontrado en el archivo "texto1.txt" y podemos ver que la linea en la que se ha encontrado la cadena es la linea numero 3 y a continuación se nos muestra la linea en cuestión.


ALGUNOS EJEMPLOS INTERESANTES

Cuando terminé el script no tenia necesidad de buscar nada en concreto, pero como tenía que probarlo pues decidí hacer algunas búsquedas en los archivos de configuración del sistema y me salieron algunos resultados interesantes, como por ejemplo los siguientes:

bsc /etc/ runlevel

Al buscar "runlevel" en los archivos de la carpeta "/etc/" se muestra en una de las coincidencias que funcionalidades están activas en cada uno de los niveles de ejecución, por ejemplo se nos indica que en el nivel 5 esta activada la red y la interfaz gráfica, y en el nivel 3 por ejemplo no esta la interfaz gráfica pero si la red.



otro ejemplo:

bsc /etc/sysconfig/ autologin



En este caso se nos indica una de las opciones del archivo "displaymanager" que indica si el sistema esta configurado para iniciar el sistema de manera automática con un usuario concreto, en mi caso esta opción la tengo vacía, así que no se hace ningún autologin.

Bueno y creo que eso es todo, si tenéis alguna duda o pregunta no dudéis en dejármela en los comentarios.

Saludos =)

1 comentario: