Tag Archives: recursivity

Renombrar recursivamente archivos y directorios

El siguiente script de bash renombra archivos y directorios convirtiendo sus nombres a minúsculas, reemplazando espacios, acentos, eñes y eliminando paréntesis.

Por defecto renombra únicamente aquellos archivos y directorios ubicados en el directorio pasado como parámetro. Es posible usar la opción-r|--recursivepara que trabaje recursivamente en todos los directorios hijos:

./rename.sh -r dir

Usando la opción-v|--verbosees posible ver en pantalla el listado de archivos modificados

./rename.sh -v -r dir

La opción-t|--testmuestra un listado de cambios a realizar sin realizar ninguno

./rename.sh -t -r dir

Ejemplo

xleo@calcifer:/tmp/music$ rename -t -r .
/tmp/music/Jaime Roos/1998 - Concierto Aniversario
./17 - Amándote.mp3 ./17_-_amandote.mp3
./02 - Victoria Abaracón.mp3 ./02_-_victoria_abaracon.mp3
./12 - Nadie Me Dijo Nada.mp3 ./12_-_nadie_me_dijo_nada.mp3
./16 - Durazno Y Convención.mp3 ./16_-_durazno_y_convencion.mp3
./01 - Si Me Voy Antes Que Vos-1.mp3 ./01_-_si_me_voy_antes_que_vos-1.mp3
./03 - El Hombre De La Calle.mp3 ./03_-_el_hombre_de_la_calle.mp3
./05 - Las Luces Del Estadio.mp3 ./05_-_las_luces_del_estadio.mp3
./07 - Piropo.mp3 ./07_-_piropo.mp3
./10 - Esta Noche.mp3 ./10_-_esta_noche.mp3
./06 - Se Va La Murga.mp3 ./06_-_se_va_la_murga.mp3
./08 - Los Futuros Murguistas.mp3 ./08_-_los_futuros_murguistas.mp3
./15 - Tal Vez Cheché.mp3 ./15_-_tal_vez_cheche.mp3
./13 - Bienvenido.mp3 ./13_-_bienvenido.mp3
./1998 - Concierto Aniversario.m3u ./1998_-_concierto_aniversario.m3u
./09 - Los Olímpicos.mp3 ./09_-_los_olimpicos.mp3
./11 - Cometa De La Farola.mp3 ./11_-_cometa_de_la_farola.mp3
./04 - Cuando Juega Uruguay.mp3 ./04_-_cuando_juega_uruguay.mp3
./14 - El Tambor.mp3 ./14_-_el_tambor.mp3
/tmp/music/Jaime Roos
./1998 - Concierto Aniversario ./1998_-_concierto_aniversario
/tmp/music
./Jaime Roos ./jaime_roos

rename.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/bin/bash
#
# @autor   Leonardo Vidarte
# @version $Id rename.sh 5 2008-06-05 15:44:45Z xleo $
#


# ********
# INIT SET
# ********
verbose=0
recursive=0
MOVE=/bin/mv
ECHO=


# ****
# HELP
# ****
help () {
cat << END
Usage : rename [-t] [-v] [-r] directory

Options:
  -v, --verbose    verbose move
  -r, --recursive  recursive rename
  -t, --test       don't move, only show change list. Implies -v.
  -?, --help       show this help

END

}


# ***************
# RENAME FUNCTION
# ***************
rename () {
   
    find -maxdepth 1 | \
    awk '{out=tolower($0); \
    gsub(" ?\& ?","_y_",out); \
    gsub("\(|\)","-",out); \
    gsub("[\340-\345]","a",out); \
    gsub("\347","c",out); \
    gsub("[\350-\353]","e",out); \
    gsub("[\354-\357]","i",out); \
    gsub("\361","n",out); \
    gsub("[\362-\366]","o",out); \
    gsub("[\371-\374]","u",out); \
    gsub("[^0-9a-z\./_-]","_",out); \
    if ($0!=out) {print "\""$0"\" "out;}}'
| \
    xargs -r -n 2 $ECHO $MOVE

}


# *************
# MAIN FUNCTION
# *************
main () {


    # ----------------
    # Recursive rename
    # ----------------
    if [ $recursive -eq 1 ]; then

        for dir in "$1"/*
        do
            if [ -d "$dir" ]; then
                cd "$dir" && search "$dir"
            fi
        done

    fi


    # ----------------------------
    # Rename files and directories
    # ----------------------------
    if [ $verbose -eq 1 ]; then
        echo "$1"
    fi

    cd "$1" && rename


}


# ***************************
# SHOW HELP WITHOUT ARGUMENTS
# ***************************
if [ $# -eq 0 ]; then
   help
   exit 1
fi


# *********
# SHOW HELP
# *********
if [[ "$1" =~ '(-h|--help)' ]]; then
   help
   exit 0
fi


# ***************
# CHECK ARGUMENTS
# ***************
while [ $# -gt 1 ]; do

    case "$1" in

        -v|--verbose)
            verbose=1
            MOVE="$MOVE --verbose"
        ;;    
        -r|--recursive)
            recursive=1
        ;;
        -t|--test)
            verbose=1
            MOVE=
            ECHO=/bin/echo
        ;;    
        *)
            echo invalid argument $1
            help
            exit 2
        ;;

    esac

    shift

done


# ****************************************
# CHECK DIRECTORY AND INVOKE MAIN FUNCTION
# ****************************************
if [ "$1" == '.' -o "$1" == '*' ]; then
    dir=$PWD
else
    dir=$1
fi

if [ -d "$dir" ]; then
    cd "$dir"
    dir=$PWD
    cd - 1> /dev/null
    main "$dir"
    exit 0
else
    echo rename: directory not found
    exit 3
fi

Otro ejemplo

Salida de./rename -r -v /shared/music > result.txt

Tags: , , ,

Torre de Hanoi

El problema de las Torres de Hanoi es curioso porque su solución es muy rápida de calcular, pero el número de pasos para resolverlo crece exponencialmente conforme aumenta el número de discos.


Resolución de la torre de cuatro discos
(imagen tomada de Wikipedia)

Es un problema que se suele plantear a menudo en ámbitos de programación, especialmente para explicar recursividad y el algoritmo para resolverlo es realmente corto:

hanoi(n, Orig, Aux, Dst)
   si (n>0) hacer
   hanoi(n-1, Orig, Dst, Aux)
   escribir(Mover Orig a Dst)
   hanoi(n-1, Aux, Orig, Dst)

A continuación se muestra una implementación Java del algoritmo. El programa se invoca de la siguiente manera:

java Hanoi n

(donde n es el numero de discos)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Hanoi
{
   public static void main(String [] args)
   {
      int numDiscs = Integer.parseInt(args[0]);
      move(numDiscs, "A", "B", "C");
   }

   protected static void move(int n, String orig, String aux, String dest)
   {
      if (n>0)
      {
         move(n-1, orig, dest, aux);
         System.out.println("Mover disco de " + orig + " a " + dest);
         move(n-1, aux, orig, dest);
      }
   }

}

Aquí pueden verse las sucesivas llamadas recursivas a la funciónmove()para el caso de 3 discos:


Read more »

Tags: , , ,