jueves, 26 de mayo de 2011

Como cambiar un texto en muchos archivos

Hola!

Mientras más trabajo con GNU/Linux (y la consola) más me impresiona su poder y flexibilidad al mismo tiempo que se mantiene la elegancia.

Una necesidad que se presenta con cierta recurrencia es la de cambiar un texto que aparece en muchos archivos por otro texto. Decidí crear un script para las personas que tengan la misma necesidad y que no lo tengan que hacer desde 0.

El script es así:

#!/bin/bash

# copyright 2011 Edmundo Carmona
# Released under the terms of Affero GPLv3

REPLACED="$1"
REPLACEMENT="$2"
FILTER="$3"
TEMP_FILE="$4"

echo Will replace "$REPLACED" with "$REPLACEMENT" on files named "$FILTER" \
    using "$TEMP_FILE" as the temporary file

find ./ -iname "$FILTER" -exec grep -Hi "$REPLACED" {} ';' | sed 's/:.*//' \
    | uniq | while read filename; do
    echo replacing on $filename
    sed "s/$REPLACED/$REPLACEMENT/g" < "$filename" > "$TEMP_FILE"
    mv "$TEMP_FILE" "$filename"
done


La forma de llamarlo es la siguiente:
- 1er parámetro: Texto que va a ser reemplazado.
- 2do parámetro: Texto que va a entrar a reemplazar.
- 3er parámetro: Filtro de archivos a buscar. Por favor, encerrarlo en comillas simples o dobles, de lo contrario bash lo va a reemplazar.
- 4to parámetro: Archivo temporal a utilizar. La sustitución se hace utilizando un archivo temporal intermedio que al final desaparece.

Por ejemplo, para reemplazar el texto Linux por GNU-Linux en los archivos .txt y utilizando el archivo temp.txt como el temporal, la llamada se haría de esta forma:

./text_change Linux "GNU-Linux" '*.txt' temp.txt

Nota: Tener cuidado de no utilizar caracteres especiales para reemplazar porque esto va a ser hecho utilizando sed. Caracteres como \ deben ser especificados con sumo cuidado. Adicionalmente, como pueden ver en el script, la búsqueda de los archivos involucrados se hace con find así que la búsqueda va a ser recursiva pasando por los subdirectorios del directorio actual.

No hay comentarios:

Publicar un comentario en la entrada