Bash script que sustituya al comando mv de UNIX

Dudas y comentarios sobre otros lenguajes de programación. Si algún lenguaje recibe suficientes preguntas le añadimos nueva categoría.
Responder
Mensaje
Autor
jvr42
Mensajes: 35
Registrado: 06/11/2012 7:43 pm
Ubicación: México

Bash script que sustituya al comando mv de UNIX

#1 Mensaje por jvr42 » 20/03/2013 5:08 pm

Hola,

Me gustaria que me dieran una ayuda o un empujon para poder escribir un script en Bash llamado mv (que sustituya al comando mv de UNIX) y que trate de cambiar el nombre del archivo especificado (usando el comando mv UNIX), pero si el archivo de destino existe, en lugar crea una especie de índice numerico, apenda al archivo de destino . Así que si escribo:

Código: Seleccionar todo

$ mv a.txt b.txt
pero b.txt ya existe, mv moverá el archivo a b.txt.1. Ahora que si b.txt.1 ya existe, debe cambiar el nombre del archivo a b.txt.2, y así sucesivamente, hasta que con éxito se puede cambiar el nombre del archivo con un nombre que no exista.

Cualquier cosa se agradece.

Avatar de Usuario
daltomi
Mensajes: 351
Registrado: 28/04/2007 7:29 pm
Ubicación: Argentina

#2 Mensaje por daltomi » 21/03/2013 3:44 am

Buenas.
Una posible solución:

Código: Seleccionar todo

#!/bin/bash

# Si argumentos != 2
if [ $# -ne 2 ]; then
    echo "Dos argumentos necesarios"
    exit 1
fi

# si destino existe...
if [ -f $2 ]; then
    for num in `seq 1000`; do #secuencia 1 a 1000
        TMP=$2.$num           # b.txt.1
        if [ -f $TMP ]; then  # si b.txt.num exite
            continue          # continuar buscando  
        else                  # si no  
            mv $1 $TMP        # mover a.txt -> b.txt.num
            break             # terminar for
        fi
    done
else
    # si destino no exite, mover normal
    # caso que no exista origen, error propio de comando mv
    mv $1 $2
fi
Saludos.

jvr42
Mensajes: 35
Registrado: 06/11/2012 7:43 pm
Ubicación: México

#3 Mensaje por jvr42 » 21/03/2013 3:29 pm

Buenas,
daltomi escribió:Buenas.
Una posible solución:
Saludos.
Gracias. Tengo otro par de preguntas si es posible:

¿Cómo se podría ajustar la variable PATH para poder reemplazar el comando mv de UNIX con este script?

La segunda:

¿Cómo implementarías un comando "limpiar" que elimine todos los archivos menos del número de versión más alto? Por ejemplo,

Código: Seleccionar todo

$ limpiar b.c 
$ ls 
a.c 
b.c ; este era b.c.2
Gracias y saludos.

Avatar de Usuario
daltomi
Mensajes: 351
Registrado: 28/04/2007 7:29 pm
Ubicación: Argentina

#4 Mensaje por daltomi » 22/03/2013 2:14 am

Buenas.
El problema es que PATH existe en dos ámbitos, el del sistema y el del usuario.
A nivel del sistema:

Código: Seleccionar todo

export PATH=/bin/:/usr/bin/:/usr/local/bin/
A nivel del usuario:

Código: Seleccionar todo

export PATH=$PATH:/home/usuario/mi_directorio
Es decir lo que ya contiene PATH( $PATH ), más lo que el usuario desea.
Como el orden de los valores tiene prioridad, no podrías colocar un script mv en mi_directorio ya que la shell buscaría primero en /usr/bin.
La solución a este problema es utilizar otro nombre, por ejemplo mv.sh o algo parecido y escribir el comando exactamente con ese nombre.
Si de todas maneras si quieres realizar esto debes cambiar PATH desde el archivo .bashrc como lo anterior.

La solución mas factible es utilizar alias, también modificando .bashrc o algunas "distros" tienen el archivo .bash_aliases

Código: Seleccionar todo

alias ll='ls -lh'
alias mp='mplayer'
alias apagar='sudo shutdown -h now'
alias mv='/home/usuario/mi_directorio/mv.sh'
Cada vez que modifiques .bashrc debes iniciar una nueva shell para actualizar los cambios del entorno. Al script se le debe activar el modo de ejecución para que funcione con alias, ejemplo: chmod +x mv.sh

En cuanto a lo segundo, entiendo se deben ir eliminado todos los archivos de la secuencia excepto el último, que debe ser movido al archivo que se pasa como argumento.

Código: Seleccionar todo

#!/bin/bash

if [ $# -ne 1 ]; then
    echo "error faltan argumentos."
    exit 1
fi

ARCHIVO=$1

if [ -f $ARCHIVO ]; then
    for NUM in `seq 1000`; do 
        TMP=$ARCHIVO.$NUM     
        if [ -f $TMP ]; then       
            NSG=`expr $NUM + 1`             #numero siguiente
            if [ -f $ARCHIVO.$NSG ]; then   #si exite siguiente 
                rm $TMP                     #eliminar anterior
                continue                    #continuar buscando
            else                            #si no existe siguiente
                mv $TMP $ARCHIVO            #mover
                exit 1                      # y salir
            fi
        fi
    done
else
    echo "error no exite el archivo $ARCHIVO"
fi
Saludos.

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado