27 enero 2005

Útiles para encontrar y borrar...y algo de "sed"

Cuando ejecutamos un comando de bash y nos dice que la lista de argumentos es demasiado larga, por ejemplo, cuando queremos borrar los miles de mensajes de correo que podemos tener en nuestro directorio de cuarentena (-bash: /bin/rm: La lista de argumentos es demasiado larga), podemos utilizar el comando find, para hacerlo de varias maneras:
  • find . -name "cadenaquesea" -exec rm {} \;
  • find . -name "cadenaquesea" -exec rm -i {} \; (El parámetro "-i" simplemente es para indicarle a rm que haga un borrado interactivo, por si no estamos seguros de que funcione bien el temita).
  • find . -name "cadenaquesea" | xargs rm; (La gente no estaba muy contenta con esta manera de hacer el borrado, porque decía que "xargs" al final perdía resultados aunque no diera el error de que la lista era larga, por eso no les gustaba.
Estas maneras de localizar y borrar las he sacado del boletín semanal de Gentoo, bueno, mejor dicho de un foro que indicaba el boletín. La gente añadía más maneras, como por ejemplo con bucles, pero bueno, para qué liarla con el potencial y la sencillez de hacerlo con find??

Otra utilidad, a partir de lo anterior es buscar una cadena recursivamente dentro de un cualquier fichero en el directorio actual:

  • find . -type f -exec grep "" {} \; -print

Utilizo "sed" para sustituir cadenas dentro de archivos, pero también está la utilidad de convertir archivos de Unix a DOS y viceversa. Recordemos que el final de línea de los archivos dos (vamos, quien dice dos, dice windows) es \r\n, y el final de línea en los archivos unix es \n, por eso aparecen los caracteres raros a veces cuando se abre con "vi" un archivo escrito en windows. Como nunca me acuerdo de las expresiones regulares concretas para hacer esto ahí van:
  • sed 's/.$//' #asume que todas las líneas terinan con retorno de carro y salto de línea, con lo que se carga todo lo del final.
  • sed 's/^M$//' #en bash y tcsh, y que se presione Ctrl-V y luego Ctrl-M, no me pispo a qué se refiere, y además, nunca me ha funcionado
  • sed 's/\x0D$//' # gsed 3.02.80, pero el script de arriba es más fácil, la verdad yo siempre he utilizado el primero
Lo anterior era en un entorno Unix por supuesto, ahora en el mismo entorno Unix queremos convertir archivos unix a dos, pues nada se hace así:

  • sed "s/$/`echo -e \\\r`/" #bajo ksh
  • sed 's/$'"/`echo \\\r`/" #bajo bash
  • sed "s/$/`echo \\\r`/" #bajo zsh
  • sed 's/$/\r/' #gsed 3.02.80
La verdad, no sé si funcionan, supongo que sí, pero nunca he necesitado hacer esto, además de no utilizar windows desde hace ya bastante tiempo.

Ya el último caso es convertir archivos unix a windows desde un entorno windows. Por supuesto primero hay que tener instalado el sed para windows:
  • sed "s/$//"
  • sed -n p
Pues con este lo mismo que en el caso anterior. Ni pajolera idea de si funciona o no, porque no utilizo el "sed" de windows ;-)

Estos casos de "sed" están sacados de la página en sourceforge.

2 comentarios:

Anónimo dijo...

A ver quien me ayuda con este proyecto.

Deseo un script que se ejecute ilimitadamente (bucle) en mi server y que busque en todos los archivos -php una "cadena_de_texto" y borre los archivos donde haya encontrado esa cadena.

he visto que find hace muy bien la búsqueda:

Código:
# find /home/mi_usuario/ -name "*.php"


este comando busca y encuentra todos los archivos php en todos el directorio citado y los de abajo también.

Ahora bien, para encontrar una cadena en todos los archivos .php de todas las carpetas hacia abajo he probado esto:

Código:
# find /home/mi_usuario/ -name "*.php" | xargs grep -niP 'cadena_a_buscar'


pero ahora necesito algo que agrupe a todo esto, incluyendo un comando que borre los archivos que contengan la cadena.

y si pudieramos agrupar todo esto en un script que se ejecute ilimitadamente sería mejor.

jmcalvar dijo...

Yo utilizaría el grep en un script. Bueno, utilizaría python, pero en su defecto grep con bash y lo pondría en el cron.