Cargando



Renombrar archivos y dar permiso de ejecución script Python

En este tutorial aprenderás a cambiar el nombre de archivos y darlos permisos de ejecución en Linux, a través de un script en Python.


ago 04 2016 12:31
Avanzado
ago 07 2016 21:28

En este tutorial sobre Python vamos a ver un script que va a cambiar la aparición de .txt por .sh en los ficheros, y además les va a dar permisos de ejecución para el usuario. Para esta tarea vamos a utilizar módulos que ya tenemos en Python, el script vale tanto para la versión 2.X, como para la 3.X, aunque la salida es ligeramente diferente, el comportamiento no cambia, como veremos más adelante.

 

Nota
El script que se va a implementar es para usar en sistemas operativos UNIX.

 

Para el ejemplo he creado una carpeta con varios ficheros, unos tienen extensión .txt, y otros no, además existe un fichero llamado test1.txt que tiene un pequeño comando: ls -l. Es para comprobar que en realidad se ejecuta, ya que el resto están de “pega” al no contener datos. El contenido de la carpeta se puede ver en la siguiente imagen:

 

renombrar_python_1.jpg

 

Si hacemos un ls -l vemos que ninguno tiene permisos de ejecución:

 

renombrar_python_2.jpg

 

Ahora vamos a pasar a ver el código completo y más abajo se explicará.

import os, sys, stat
from subprocess import Popen, PIPE

if(len(sys.argv) < 2):
    print("Se requiere la ruta donde buscar")
    sys.exit(0)
elif(not os.path.exists(sys.argv[1])):
    print("No se encuentra: "+str(sys.argv[1]))
    sys.exit(0)

process = Popen(["find", sys.argv[1]], stdout=PIPE, stderr=PIPE)

if not process.stderr.read():
    num = 0
    for line in process.stdout.readlines():
        lineNew = line.decode("UTF-8").strip()
        if(".txt" in lineNew and os.path.isfile(lineNew)):
            new = lineNew.replace(".txt",".sh")
            os.rename(lineNew, new)
            os.chmod(new, stat.S_IXUSR+stat.S_IRUSR+stat.S_IWUSR+stat.S_IRGRP+stat.S_IXGRP)
            num += 1
    print("Trabajo hecho, cambiados",num,"ficheros")
else:
    print("Error")
Vamos a empezar con la explicación del código paso a paso, lo primero que hacemos es importar los módulos que vamos a necesitar.
import os, sys, stat
from subprocess import Popen, PIPE
Acto seguido comprobaremos si se nos ha pasado un argumento y es una ruta, para ver si seguimos con el script o no.
if(len(sys.argv) < 2):
    print("Se requiere la ruta donde buscar")
    sys.exit(0)
elif(not os.path.exists(sys.argv[1])):
    print("No se encuentra: "+str(sys.argv[1]))
    sys.exit(0)
Para continuar usamos Popen del módulo subprocess, capturamos la salida estándar y la de error, esto lo hacemos ayudándonos de PIPE, una tubería. Ahora podremos leer de la tubería como si fuera un archivo.
process = Popen(["find", sys.argv[1]], stdout=PIPE, stderr=PIPE)
Para saber si continuar comprobamos si existe error (almacenado en process.stderr) con el siguiente if:
if not process.stderr.read():
Si existe algún error se pintará por pantalla Error (esto es por la rama else, que no tiene mayor explicación) y termina el programa. Si no, lo que vamos a hacer es leer de la tubería de salida estándar (stdout). Lo hacemos línea a línea con un for, debemos decodificar la salida, en este caso opto por UTF-8, ya que con ASCII daría errores con las tildes por ejemplo.

 

Si seguimos mirando el bucle for, vemos que comprobamos si la línea leída contiene .txt, si es así también se comprueba que sea un fichero (no nos interesa cambiar una carpeta que contenga .txt). Si esto se cumple usamos la función replace de Python para cambiar .txt por .sh, y luego con la función chmod del módulo os le damos permisos, que serán ejecución, lectura y escritura para el usuario, lectura y ejecución para el grupo y nada para otros. Como ves usamos el módulo stat.

 

La variable num que habrás visto en el código se utiliza simplemente para llevar la cuenta del número de ficheros que cambiamos y así al final poder mostrar información por pantalla.

for line in process.stdout.readlines():
        lineNew = line.decode("UTF-8").strip()
        if(".txt" in lineNew and os.path.isfile(lineNew)):
            new = lineNew.replace(".txt",".sh")
            os.rename(lineNew, new)
            os.chmod(new, stat.S_IXUSR+stat.S_IRUSR+stat.S_IWUSR+stat.S_IRGRP+stat.S_IXGRP)
            num += 1
Al terminar el bucle for, lo que hacemos es mostrar la información de la que hablamos, aquí es donde encontraremos la diferencia entre la versión 2.x y 3.x, ya que las comas antes y después de num en la versión 2 lo parte en una lista y en la 3 te lo muestra normal (sin lista).
 print("Trabajo hecho, cambiados",num,"ficheros")
Esto se puede cambiar para que se interprete igual usando el + y convirtiendo a string la variable num con la función str, o a través de los %, a continuación se ponen los 2 códigos:
print("Trabajo hecho, cambiados "+str(num)+" ficheros")
print("Trabajo hecho, cambiados %d ficheros" % num)
Se dejó de la primera forma para que se vea que entre versiones de Python existen cambios (pueden ser pequeños como en este caso, pero puede que algo que funcione en la versión 3 no lo haga en la 2, y viceversa).

 

Ahora y ya casi para terminar el tutorial vamos a ejecutar el código y ver cómo funciona, a continuación dejo 2 imágenes de la ejecución, usando Python 3.x en la primera, y en la segunda Python 2.x:

 

renombrar_python_3.jpg

 

renombrar_python_6.jpg

 

Aquí apreciamos las ligeras diferencias. Ahora vamos a ver cómo queda la carpeta testing que vimos antes:

 

renombrar_python_4.jpg

 

Se han cambiado los 4 archivos que tenían .txt y ahora tienen .sh, parece que solo es ejecutable el archivo test1.sh, esto es así porque el resto no contienen datos. Vamos a ejecutar el fichero test1.sh, que lo único que hará es lanzar el ls -l que dijimos que contenía, y así nos sirve para ver los permisos.

 

renombrar_python_5.jpg

 

Hasta aquí llega el tutorial, por si es de interés se pone a continuación un enlace a otro tutorial sobre Python: buscar por nombre de archivos.


¿Te ayudó este Tutorial?


1 Comentarios


Raquel Alvarez
ago 16 2016 13:53

Yo sabía hacer esto con Bash, pero Python es más divertido. GrAcIaS

No esperes más y entra en Solvetic
Deja tus comentarios y aprovecha las ventajas de la cuenta de usuario ¡Únete!

X