Domando los archivos con espacios en su nombre desde la terminal

por | 4 diciembre, 2015

domando

Un tip de esos sencillos, de 2º de Linux y fundamentos básicos de Bash (si sois usuarios veteranos, de esos que compilan kernels mientras devoran con parsimonia el nú que cazaron la noche anterior, os lo podéis saltar) sobre como lidiar en la terminal con los archivos que tienen en su nombre espacios sin que den error al hacer operaciones y en caso necesario poder renombrarlos de forma masiva para eliminar dichos espacios.

Alguna gente para evitar errores en su manejo, utiliza las llamadas barras inversas (\) para representar dicho espacio lo que me parece algo incomodo y de una estética ruin, la gente que tenemos estilo al usar la terminal (XD) preferimos usar comillas –simples o dobles– para preservar el nombre del archivo y manejarlo sin problemas en la linea de comandos.

Manejo sencillo en la terminal

Lo podemos ver en algunos ejemplos básicos:

  • ir a un directorio determinado
cd “una carpeta loca”
  • copiando un documento:
cp 'y la europea que?.txt' /home/tannhausser
  • o moviendo archivos de aquí para allá:
mv 'tu compila que nosotras limpiamos la sangre.avi' 'telefono rojo volamos hacia Redmond.mp4' 'Mucho FUD y pocas news, Mark.mp4' 'el señor de los pingüinos.flv' /home/tannhausser/pelis

espacios-nombres_archivos

Renombrado de archivos eliminando sus espacios

Si no queremos andarnos con vueltas y preferimos renombrar todos los archivos, eliminando los espacios sobrantes y sustituyéndolos por guiones, lo podemos hacer con una linea de comandos que vi en Commandlinefu.

Nos vamos a la carpeta donde están los archivos y desde ahí ejecutamos:

for f in * ; do mv "$f" "${f// /-}" ; done

Una vez ejecutado vamos a ver que los espacios entre palabras desaparecen, siendo sustituidos por guiones de tipo medio (o como diablos se llamen)

Me encanta el aroma de los tips sencillos en fin de semana 🙂

Imagen (modificada) | Duchess Flux (CC BY-NC 2.0)

12 pensamientos en “Domando los archivos con espacios en su nombre desde la terminal

  1. portaro

    Excelente , en mi caso ni idea de esto y mira que por ejemplo el LXDE tiene unos problemillas con espacios que ni contao una vez lo hace bien y la gran parte de veces no.
    Podria por lo tanto ser una muy bella guia de sobrevivencia en este tipo de escritorio para evitar andar nombrando a mano , asi que gracias por compartir!

    Responder
    1. tannhausser Autor

      Creo que es un problema al que todo usuario intermedio de Linux, que empieza a tocar la terminal se enfrenta alguna vez, como acceder a una determinada carpeta o abrir un archivo con espacios desde la consola sin que de error.

      No se como hay gente que sigue recomendando lo del guion invertido, es un rollo tener que ponerlo entre cada palabra, mejor unas comillas y fuera.

      Y el comando del final, para eliminar los espacios, de los que probé es el que más me gustó. Y de ese no me voy a acordar ni loco, así que mejor tenerlo a mano 😉
      Saludos y gracias a ti por pasarte y comentar

      Responder
  2. Renamer

    Esa orden usa «parameter expansion» de bash, que creo que no es estándar POSIX.

    Prefiero la clásica herramienta «rename» que viene con cualquier instalación de Perl. Sobre todo porque evita sobreescribir ficheros accidentalmente y tiene previsualización con la opción –no-act:
    $ rename -n ‘s/ /-/g’ *

    Responder
    1. tannhausser Autor

      Lo conozco, en Arch Linux y derivadas hay que instalar perl-rename para que funcione, sería algo así:

      perl-rename -n "s/ /-/g" *

      Un saludo y gracias por la sugerencia

      Responder
      1. Renamer

        Entonces cambio lo de «todas las instalaciones de Perl» por «la instalación de Perl de Debian y derivadas».
        Además, cuidado no confundirlo con el «rename.ul» del paquete util-linux en Debian, que es peor y peligroso en sobreescritura.

        Responder
    1. tannhausser Autor

      Gracias amigo! se hace lo que es puede (aunque ya sabes para mi es un placer escribir, no soy de esos bloggers llorones que se quejan por el gran esfuerzo que hacen y el poco reconocimiento que tienen XD)

      En realidad querría dar más noticias (o tips) reduciendo el texto de las mismas, pero al final siempre me acabo enrollando y me quedan temas en el tintero, de los que hablar.

      Quizás sino probara todos los programas y distros antes de escribir sobre ellos me daría más tiempo, pero claro entonces ya sería un aburrimiento total (para mi)…

      Responder
  3. T°ñ°

    en cuanto a renombrar un comando más simple pero igual de efectivo sería:
    $ rename ‘s/ /_/g’ /ubicación-de-los-archivos-o-carpetas
    si quiero reemplazar con guió bajo los espacios en los nombres de mis archivos m4a en la carpeta canciones:
    $ rename ‘s/ /_/g’ /home/yo/Música/canciones/*.m4a

    Responder
  4. Swicher

    No se si Tannhausser pensaba hacer un post al respecto pero como complemento al articulo dejo otro tip para el siguiente caso: ¿que pasa si quiero procesar una lista de archivos que obtengo como resultado de otro comando (generalmente un find o un ls) pero no me interesa sacarles los espacios?
    La situación mas reciente en que me ocurrió esto fue al querer hacer un select en varias bases de datos SQLite (y casi todas tienen nombres con espacios), en mi caso lo resolví así:

    IFS_backup=$IFS
    IFS=$(echo -en "\n\b")
    for archivo in $(ls *places.sqlite); do
    sqlite3 "$archivo" 'select url, title from moz_places where title like "%algo%" and url not like "%algunsitio.com%" and url not like "%otrositio.net%";';
    done
    IFS=$IFS_backup

    Seguramente habrá formas mejores de hacer lo mismo pero el truco esta en cambiar la variable $IFS (que determina el separador de campos usado dentro de la shell, aquí se explica mejor su función) para que use saltos de linea en lugar de espacios/tabulaciones.

    Responder
    1. Renamer

      1) Tu problema de espacios desaparece usando la expansión de ficheros de la shell. Además, IFS no arregla otros problemas como expansión del historial con ! en modo interactivo.
      Dir actual: for archivo in *places.sqlite; do … ; done
      Subdirs: for archivo in **/*places.sqlite; do … ; done
      Ambos: for archivo in *places.sqlite **/*places.sqlite; do … ; done

      2) El programa ls no está recomendado para scripting porque usa newline como delimitador y su modo recursivo es pobre (sin nombre completo, sin filtrado, sin recorrido DFS).
      Por usarlo, tu script falla con nombres de ficheros con \n o \b (¿para qué aceptas backspace de todas formas?). Los únicos carácteres inválidos en un sistema de ficheros Unix son / (separador de dirs) y \0 (null, finalizador de cadenas en lenguaje C). Por tanto, el único robusto es \0 como usa find -print0 | xargs -0, grep --null, sort -t $'\0' y otros.
      Aunque para tu caso ni siquiera hacen falta combos:
      find -maxdepth 1 -name ‘*places.sqlite’ -execdir sqlite3 ‘{}’ ‘select url, title from moz_places where title like «%algo%» and url not like «%algunsitio.com%» and url not like «%otrositio.net%»;’ \;
      find es mucho más potente que la expansión de shell: formato personalizado con -printf, filtrado, habilidad para combinarlo con xargs -0, acciones ya preparadas (-ls, -delete), varias acciones de una sola pasada (operador coma)… Es una *inversión* aprenderlo.

      3) Puedes reemplazar IFS=$(echo -en «\n\b») por IFS=$’\n’. Mira la sección QUOTING de man 1 bash.

      Responder
  5. rolo

    tambien funciona la barra invertida para suplir los espacios cp hola\ mundo.txt holamundo.txt
    o poniendo la primer letra del archivo y apretar el tabulador (estando dentro del directorio)
    salu2s

    Responder

Responder a D'ArtagnanCancelar respuesta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.