Quantcast
Viewing all articles
Browse latest Browse all 2728

Poesía Binaria: Cómo extraer ruta, nombre de fichero y extensión en Bash de forma nativa para nuestros scripts

Image may be NSFW.
Clik here to view.
7959831794_e5699df68b_k

Bash tiene infinidad de opciones, y en los últimos años se ha extendido muchísimo y nos permite hacer cosas muy chulas. Aunque un sistema con tantas opciones como este, es también un poco lioso y difícil de aprender. Por eso en ocasiones viene bien una chuleta para realizar operaciones sencillas que pueden llegar a ser un poco rebuscadas como obtener el nombre de un fichero y su extensión.

Bash, al ser un intérprete de comandos de consola, una de sus principales funciones es trabajar con archivos y cuando queremos utilizar archivos, tenemos que jugar con sus posibles nombres, para ello, deberíamos poder extraer fácilmente la ruta de un archivo, su nombre y separarlo de la extensión. Por ejemplo, si queremos transformar varios archivos de un directorio de jpg a png, o hacer un script que trate de forma los archivos de imagen y de otra los vídeos, o incluso contar cuántos archivos tienen qué extensión…

Para ello, y a modo de autochuleta también, vamos a plantear varios ejemplos en los que se utilizan los modificadores # y % de expansión de parámetros en Bash:

1
2
3
4
5
6
7
#!/bin/bash
FICHERO="archivo.txt"
NOMBRE="${FICHERO%.*}"
EXTENSION="${FICHERO##*.}"

echo$NOMBRE
echo$EXTENSION

Si ejecutamos esto veremos que primero se mostrará el nombre (archivo) y luego la extensión (txt), aunque, esto deberíamos complicarlo un poco más, y plantearnos preguntas para verificar que funciona en todos los casos, por ejemplo, ¿qué pasaría si el archivo no tiene extensión? En este caso, devolvería el mismo nombre del archivo, y eso puede darnos problemas, para solucionarlo, plantearemos EXTENSION de la siguiente forma:

1
EXTENSION=$([["$FICHERO" = *.*]]&&echo"${FICHERO##*.}")

Ahora bien, ¿qué pasaría si nos pasan un archivo con doble extensión? Como “archivo.tar.bz2″, la variable NOMBRE contendría (archivo.tar) y EXTENSION contendría (bz2). Esto puede ser útil en ciertas ocasiones, por ejemplo, podríamos recorrer todas las posibles extensiones del archivo:

1
2
3
4
5
6
7
8
9
10
11
FICHERO="archivo.tar.bz2"
NOMBRE="${FICHERO%.*}"
EXTENSION="${FICHERO##*.}"

echo$EXTENSION

while[-n"$EXTENSION"]; do
   FICHERO="${FICHERO%.*}";
   EXTENSION=$([["$FICHERO" = *.*]]&&echo"${FICHERO##*.}");
   echo$EXTENSION;
done

Pero si queremos extraer todas las extensiones juntas del archivo, deberíamos hacer:

1
EXTENSION=$([["$FICHERO" = *.*]]&&echo"${FICHERO#*.}")

Y si queremos el nombre sin ninguna extensión:

1
NOMBRE="${FICHERO%%.*}"

Lo que variamos es el número de % y de # que colocamos. En este caso, si utilizamos # estaremos eliminando el prefijo de un patrón, es decir, la parte a la izquierda, y como eliminamos *. queremos decir que eliminamos todo lo que hay delante del punto, ahora si usamos un sólo # estaremos eliminando lo menor posible y si usamos dos, lo mayor posible. De esta forma ${FICHERO#*.} al eliminar poco, nos devuelve todas las extensiones y ${FICHERO#*.}, al encontrar el patrón más grande posible, muestra sólo la última extensión.

De esta forma, nos podemos crear nuestras propias funciones:

1
2
3
4
5
6
7
8
9
10
11
function my_filename()
{
  localFILE="$1"
  [["$2" = "1"]]&&echo"${FILE%.*}"||echo"${FILE%%.*}"
}

function my_extension()
{
  localFILE="$1"
  [["$FILE" = *.*]]&&([["$2" = "1"]]&&echo"${FILE#*.}"||echo"${FILE##*.}")
}

Así si hacemos varias llamadas:

$ my_filename archivo
archivo
$ my_filename archivo.tar
archivo
$ my_filename archivo.tar.bz2
archivo
$ my_filename archivo.tar.bz2 1
archivo.tar

$ my_extension archivo

$ my_extension archivo.tar
tar
$ my_extension archivo.tar.bz2
bz2
$ my_extension archivo.tar.bz2 1
tar.bz2

Incluyendo directorios

Si queremos que estas funciones separen también nombres de archivo de directorios tenemos varias opciones. Una de ellas es utilizar basename y dirname, que son dos comandos que muchas veces están disponibles para extraer nombres de archivos y nombres de directorios, así:

$ basename /usr/share/sane/xsane/archivo.tar.bz2
archivo.tar.bz2
$ dirname /usr/share/sane/xsane/archivo.tar.bz2
/usr/share/sane/xsane

Aunque si queremos una solución puramente hecha en Bash, y así evitar hacer llamadas externas y ganar algo de rendimiento podemos utilizar las mismas técnicas anteriores. Es más, primero, vamos a incluir rutas de archivo con las funciones anteriores, a ver qué pasa:

$ my_filename “/usr/share/sane/xsane/archivo.tar.bz2″
/usr/share/sane/xsane/archivo
$ my_extension “/usr/share/sane/xsane/archivo.tar.bz2″
bz2

En principio el nombre incluye la ruta completa, pero la extensión se comporta bien, aunque si el directorio contiene un punto también…

$ my_extension /etc/init.d/lm-sensors
d/lm-sensors

Por tanto, primero vamos a intentar eliminar las rutas, y extraer el nombre de archivo base. Esto lo podemos hacer basándonos en el patrón entre la última barra y el final del nombre, o lo que es lo mismo, eliminando desde el principio del nombre hasta la última barra:

$ echo “${FICHERO##*/}”

y para extraer la ruta solamente, podremos utilizar algo similar a la extensión:

$ $([[ “$FICHERO” = */* ]] && echo “${FICHERO%/*}”)

Esto mismo, lo podemos trasladar a las funciones, de la siguiente forma:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function my_filename()
{
  localFILE="$1"
  FILE="${FILE##*/}"
  [["$2" = "1"]]&&echo"${FILE%.*}"||echo"${FILE%%.*}"
}

function my_extension()
{
  localFILE="$1"
  FILE="${FILE##*/}"

  [["$FILE" = *.*]]&&([["$2" = "1"]]&&echo"${FILE#*.}"||echo"${FILE##*.}")
}

function my_dirname()
{
  localPATH="$1"

  [["$PATH" = */*]]&&echo"${PATH%/*}"
}

Con las que tendremos un acceso más fácil y amigable para nuestros scripts.

Foto principal: Christopher Adams

The post Cómo extraer ruta, nombre de fichero y extensión en Bash de forma nativa para nuestros scripts appeared first on Poesía Binaria.


Viewing all articles
Browse latest Browse all 2728

Trending Articles


Ka longiing longsem kaba skhem bad kaba khlain ka pynlong kein ia ka...


UPDATE SC IDOL: TWO BECOME ONE


Pokemon para colorear


Sapos para colorear


Love Quotes Tagalog


Two timer Sad tagalog Love quotes


Top 7 Lies of Boys


Re:Mutton Pies (lleechef)


Hato lada ym dei namar ka jingpyrshah jong U JJM Nichols Roy (Bah Joy) ngin...


EASY COME, EASY GO


FORECLOSURE OF REAL ESTATE MORTGAGE


HOY PANGIT, MAGBAYAD KA!


Girasoles para colorear


Presence Quotes – Positive Quotes


Long Distance Relationship Tagalog Love Quotes


Tropa Quotes


“Mali man na ikaw ay ibigin ko, akoy iibig padin sayo”


RE: Mutton Pies (frankie241)


Vimeo 10.7.0 by Vimeo.com, Inc.


Vimeo 10.7.1 by Vimeo.com, Inc.