3  Administración de archivos y directorios

3.1 Sistema de archivos de Linux

El sistema de archivos de Linux se organiza de manera jerárquica, en donde todos los directorios y archivos descienden de un elemento común llamado directorio raíz (root en inglés) el cual se representa con el carácter de barra inclinada / (slash en inglés). En la Figura 3.1 Se puede observar la estructura del sistema de archivos de Linux. Observe cómo todos los elementos se desprenden del directorio raíz (/), es decir que están contenidos en él.

Figura 3.1. Estructura del sistema de archivos de Linux generado con el comando tree. La opción -L 1 hace que tree muestre los directorios y archivos del nivel 1 contenidos en el directorio raíz (/). Observe los elementos con el símbolo ->. Estos elementos son enlaces simbólicos, algo parecido a los enlaces directos en Windows. En los enlaces simbólicos de la figura, el nombre (parte izquierda) está enlazado o apunta a una ubicación destino (parte derecha). Por ejemplo, en bin -> usr/bin, bin es un enlace (o apunta) a la ubicación usr/bin. En la figura, cada elemento tiene un color determinado según su tipo: directorios en azul, enlaces simbólicos en cyan (aguamarina), y archivos en blanco.

Como se puede observar en la Figura 3.1, hay directorios que aparecen con una barra inclinada en medio, p. ej. usr/bin. Esta estructura es llamada ruta o path, y describe la ruta o dirección hasta la ubicación de un elemento del sistema de archivos del SO. En el caso anterior, podemos decir que bin se encuentra dentro de usr. Cada elemento se separa por medio de una barra inclinada (/), de manera parecida a las rutas en Windows que utilizan barras invertidas (\, p. ej. C:\Users\MiUsurio). En la Tabla 3.1 se encuentran descritos los directorios más relevantes de Linux.

Tabla 3.1. Directorios m’as importantes del sistema de archivos de Linux.
Directorio Descripción
bin Continene archivos ejecutables, también llamados binarios (binaries), esenciales del SO.
boot Contiene archivos necesarios para el arranque (boot) del SO.
dev Este directorio contiene archivos de los dispositivos de la máquina en uso por el SO, icluidos los discos internos o externos montados.
home Contiene los directorios de los usuarios del SO. Más información en la Sección 3.1.1.
lib Este folder contiene archivos de bibliotecas (libraries) requeridos para el funcionamiento de distintos programas.
mnt Este directorio es usado para montar temporalmente dispositivos de almacenamiento como discos duros externos.
opt Aquí se almacenan arhivos de programas opcionales (optional), los cuales no vienen incluidos con la distribución Linux y son instalados independientemente por los usuarios. Aquí se instalan por ejemplo programas como Google Chrome.
root Existe un usuario diferente de todos los demás, el root. Este usuario tiene control absoluto sobre los procesos y archivos del SO, por eso se puede decir que tiene “superpoderes”. Este directorio es su home, y como puede verse, no está dentro del directorio /home como el resto de los usuarios.
sbin Como en el caso del directorio /bin, contiene archivos binarios pero destinados a ser usados por el usuario root.
tmp Aquí se almacenan archivos temporales usados por el SO y programas. El contenido de este archivo se elimina cada vez que el SE se reinicia.
usr Este directorio es de sólo lectura y contiene aplicaciones y archivos que son usados y compartidos por todos los usuarios del sistema.
var Parecido a /usr pero se pude escribir en él. Contiene archivos de historial del sistema (logs).
Nota

En Linux todo elemento en el sistema de archivos es un archivo, incluso los directorios. Así, cada archivo puede ser de tres tipos: regular, directorio, o especial (enlaces simbólicos, de bloque, entre otros).

3.1.1 El directorio personal home

Cada usuario tiene un directorio personal el cual se denomina de manera genérica como home. El directorio home de cada usuario siempre está ubicado dentro del directorio del sistema /home. El nombre del directorio home de un usuario siempre corresponde a su nombre de usuario. Por ejemplo, mi nombre de usuario es hector, así entonces mi directorio home lleva el nombre hector. El directorio home contiene todos los archivos de un usuario y solo es accesible por dicho usuario. Cuando un usuario abre una terminal, el directorio actual de inicio es su directorio home. Como se dijo en la Sección 2.3, el directorio home se representa en la línea de comandos con con el carácter ~. (virgulilla).

3.1.2 Rutas absolutas y relativas

En Linux, frecuentemente se requiere especificar la ubicación de archivos o directorios, por ejemplo para pasar un archivo a un comando para que sea procesado, o simplemente para navegar por distintos directorios desde la terminal. La ubicación de un archivo o directorio en Linux se especifica por medio de una ruta (path), la cual puede ser entendida como la “dirección” donde reside dicho archivo o directorio. Los elementos de una ruta que describen las ubicaciones, siempre están separados por barras inclinadas /. Una ruta puede ser de dos tipos: absoluta o relativa.

Una ruta absoluta es aquella que especifica la ubicación desde la raíz del sistema de archivos, es decir, el directorio root representado con la barra inclinada (/). Por ejemplo, en mi directorio home existe otro directorio llamado “Documentos”. Dentro de este último directorio tengo un documento de texto llamado mi_texto.txt. La ruta absoluta a este archivo será entonces /home/hector/Documentos/mi_texto.txt. Observe que la ruta describe todos los directorios desde la raíz / hasta llegar al archivo en cuestión.

Una ruta relativa es aquella que especifica la ubicación de un archivo o directorio, con base en la ubicación actual (“relativa” a la ubicación actual). Siguiendo con el ejemplo anterior del archivo mi_texto.txt, suponga que acaba de abrir la terminal y por tanto se encuentra ubicado en su directorio home. La ruta relativa de este archivo será Documentos/mi_texto.txt. Observe que la ruta describe la ubicación partiendo de su ubicación actual (home), ignorando los directorios padre que lo contienen (/home/hector). Suponga ahora que está ubicado dentro del directorio Documentos; la ruta relativa del archivo en este caso sería mi_texto.txt, es decir, el nombre del archivo. Siguiendo la regla de la ruta relativa, se especifica la ubicación del archivo con base en la ubicación actual e ignorando los directorios que lo contienen (/home/hector/Documentos).

Para entender las rutas absolutas y relativas, se puede pensar en una analogía para ubicar objetos dentro de su casa. Suponga que desea especificar la ubicación de un bolígrafo que se encuentra sobre su escritorio. La ruta absoluta para ubicar el bolígrafo requiere que se especifique toda la dirección empezando desde la ciudad (ciudad, barrio, intersección de calle y carrera (o similar), número de la casa, habitación, escritorio, bolígrafo): /cali/san_fernando/calle4b_cra36/casa00/hab01/escritorio_cafe/boligrafo_azul. Ahora suponga que usted se encuentra en su casa; en este caso la ruta relativa al bolígrafo sería hab01/escritotio_cafe/boligrafo_azul, es decir, para ubicar el bolígrafo, no es necesario especificar la ciudad, barrio, intersección, y casa. Si usted estuviese sentado al frente de su escritorio, la ruta relativa sería aún más corta: boligrafo_azul.

3.2 Comandos

Ahora se explicarán los comando más comunes para la gestión de archivos y directorios en Linux. La siguiente tabla muestra el Uso de los comando que serán explicados. Note que hay tres columnas: el comando, nemotecnia, y la descripción. En la columna nemotecnia se presenta la regla para recordar más fácilmente el nombre del comando, que generalmente es una abreviación en inglés de la acción/tarea que realiza dicho comando.

Tabla 3.2. Comandos para adminstración de archivos y directorios.
Comando Nemotecnia Descripción
pwd print working directory Muestra el directorio de trabajo
ls list Lista (muestra) los archivos de un directorio
cd change directory Cambia la ubicación actual de trabajo a otro directorio
touch tocar Crea un archivo vacío (sin contenido). Realmente modifica la fecha y hora de modificación (timestamp) de un archivo, pero usualmente se usa con el proósito descrito al principio.
mkdir make directory Crea (“hace o fabrica” del inglés make) un directorio
cp copy Copia archivos o directorios
mv move Mueve archivos o directorios de un logar a otro. También se usa para renombrar.
cat concatenate Muestra el contenido de uno o varios archivos. También se usa para concatenar (pegar) varios arcivos en uno solo.
Importante

A partir de aquí se espera que usted ejecute los comandos en su terminal. La práctica es fundamental para aprender los comandos y sentirse cómodo con el uso de la línea de comandos.

3.2.1 pwd

Uso
pwd  

Imprime el directorio de trabajo, es decir la ubicación actual en la línea de comandos.

Como se vio en el capítulo anterior, recién se inicia la terminal, el directorio de trabajo es el home (directorio personal) del usuario:

pwd
/home/hector

Observe que el resultado de pwd es una ruta absoluta, pues empieza desde el directorio raíz (/)

3.2.2 ls

Uso
ls [OPCIONES] [DIRECTORIO]

Lista el contenido del(de los) directorio(s) especificado(s) mediante [DIRECTORIO].

Opciones útiles:

  • -l: Formato largo (long)
  • -a: Lista todos (all) los archivos, incluso los ocultos
  • -h: Con -l y -s imprime los tamaños de archivo en unidades comprensibles para humanos.

Si no se especifica el directorio, ls mostrará el contenido del directorio actual de trabajo, que en este caso es el home:

ls
bin
Descargas
Documentos
Escritorio
Imágenes
mambaforge
Música
Plantillas
projects
Público
R
snap

Ahora se le ordena a ls mostrar los archivos en /usr:

ls /usr
bin
games
include
lib
lib32
lib64
libexec
libx32
local
sbin
share
src

Observe la diferencia en el formato de salida cuando se usa la opción -l:

ls -l -h ~
total 48K
drwxrwxr-x 2 hector hector 4,0K mar 24 16:08 bin
drwxr-xr-x 6 hector hector 4,0K mar 26 19:43 Descargas
drwxr-xr-x 2 hector hector 4,0K ene 18 20:29 Documentos
drwxr-xr-x 2 hector hector 4,0K ene  1 17:28 Escritorio
drwxrwxr-x 2 hector hector 4,0K mar 27 14:40 Imágenes
drwxrwxr-x 9 hector hector 4,0K mar 27 14:38 mambaforge
drwxrwxr-x 2 hector hector 4,0K mar 27 14:40 Música
drwxr-xr-x 2 hector hector 4,0K ene  1 17:28 Plantillas
drwxrwxr-x 9 hector hector 4,0K mar 27 13:10 projects
drwxrwxr-x 2 hector hector 4,0K mar 27 14:40 Público
drwxrwxr-x 3 hector hector 4,0K mar 27 14:41 R
drwx------ 5 hector hector 4,0K mar  5 17:14 snap

En el comando anterior además de especificar el directorio (home o ~). Se usaron las opciones -l y -h. Como puede ver hay nueve columnas con información diferente para cada elemento de la lista. Veamos las partes de la fila del elemento Documentos:

  • drwxr-xr-x: cadena que muestra los permisos de archivo1 en cuatro partes:
    • d: tipo de archivo. Aquí la d significa que se trata de un directorio;
    • rwx: permisos del propietario (owner), r lectura (read), w escritura (write), y x ejecución (execution)
    • r-x: permisos del grupo (group) al que pertenece el propietario. Note que aparece - en lugar de w, es decir que no hay permiso de escritura.
    • r-x: permisos para otros (other) usuarios diferentes del propietario
  • 2: número de enlaces duros (hard links2)
  • hector: el propietario del archivo/directorio
  • hector: el grupo al que pertenece el propietario
  • 4,0K: el tamaño del archivo/directorio. En este caso se muestra en Kilobytes gracias a la opción -h
  • ene 1 17:28: la fecha (mes, día y hora) de creación/modificación del archivo
  • Documentos: el nombre del elemento, en este caso un directorio

Existen archivos ocultos en Linux los cuales no son visibles normalmente con ls o en el explorador gráfico de archivos. Generalmente los archivos ocultos corresponden a archivos de configuración, y por esta razón, conviene tenerlos “ocultos” para protegerlos de modificaciones o eliminación accidentales. Para visualizarlos se usa la opción -a con ls:

ls -a
.
..
.bash_logout
.bashrc
.bashrc.bak
bin
.cache
.common.config.sh
.conda
.config
.customrc.sh
Descargas
Documentos
.dotfiles
.dotnet
Escritorio
.fonts
.gitconfig
.gnupg
Imágenes
.java
.local
mambaforge
.mozilla
Música
.ncbi
.parallel
.pki
Plantillas
.profile
projects
Público
.r
R
.Rhistory
.shutter
snap
.ssh
.sudo_as_admin_successful
.thunderbird
.TinyTeX
.vboxclient-clipboard.pid
.vscode
.vscode-R
.wget-hsts
.zcompdump
.zlogin
.zlogout
.zprezto
.zpreztorc
.zprofile
.zshenv
.zsh_history
.zshrc

Como puede ver, existen varios archivos ocultos, entre los que se destacan .profile y .bashrc que contienen configuración de la sesión de Bash, el intérprete de comandos (shell) por defecto de Ubuntu Linux.

Importante

Note los dos primeros elementos en la salida del comando ls -a: . (punto) y .. (punto punto). Todo directorio en Linux tiene estos dos elementos, los cuales son directorios. El . representa el mismo directorio listado, y el .. representa el directorio padre, es decir el directorio que contiene al directorio listado.

Se pueden combinar varias opciones en en una sola “palabra”, es decir con un solo - al principio, para modificar el comportamiento de los comandos de varias maneras. Por ejemplo en el siguiente comando se usan las opciones -lhtr para forzar a ls a mostrar el formato largo (-l), con tamaños de archivo entendibles por el humano (-h), ordenados por fecha de creación/modificación (-t), de manera inversa (-r), es decir, del más antiguo al más reciente. Además, se usa una ruta absoluta para especificar el directorio que se desea listar:

Importante

Usted deberá cambiar hector por su propio nombre de usuario en este y el resto de ejemplos que involucren el directorio home.

ls -lhtr /home/hector
total 48K
drwxr-xr-x 2 hector hector 4,0K ene  1 17:28 Plantillas
drwxr-xr-x 2 hector hector 4,0K ene  1 17:28 Escritorio
drwxr-xr-x 2 hector hector 4,0K ene 18 20:29 Documentos
drwx------ 5 hector hector 4,0K mar  5 17:14 snap
drwxrwxr-x 2 hector hector 4,0K mar 24 16:08 bin
drwxr-xr-x 6 hector hector 4,0K mar 26 19:43 Descargas
drwxrwxr-x 9 hector hector 4,0K mar 27 13:10 projects
drwxrwxr-x 9 hector hector 4,0K mar 27 14:38 mambaforge
drwxrwxr-x 2 hector hector 4,0K mar 27 14:40 Público
drwxrwxr-x 2 hector hector 4,0K mar 27 14:40 Música
drwxrwxr-x 2 hector hector 4,0K mar 27 14:40 Imágenes
drwxrwxr-x 3 hector hector 4,0K mar 27 14:41 R

Observe el siguiente ejemplo. Aquí se usan las mismas opciones (-lhrt) y se especifica el directorio actual por medio del punto (.). Verá que el resultado es idéntico al ejemplo inmediatamente anterior dado que la ubicación actual es el home:

ls -lhrt .
total 48K
drwxr-xr-x 2 hector hector 4,0K ene  1 17:28 Plantillas
drwxr-xr-x 2 hector hector 4,0K ene  1 17:28 Escritorio
drwxr-xr-x 2 hector hector 4,0K ene 18 20:29 Documentos
drwx------ 5 hector hector 4,0K mar  5 17:14 snap
drwxrwxr-x 2 hector hector 4,0K mar 24 16:08 bin
drwxr-xr-x 6 hector hector 4,0K mar 26 19:43 Descargas
drwxrwxr-x 9 hector hector 4,0K mar 27 13:10 projects
drwxrwxr-x 9 hector hector 4,0K mar 27 14:38 mambaforge
drwxrwxr-x 2 hector hector 4,0K mar 27 14:40 Público
drwxrwxr-x 2 hector hector 4,0K mar 27 14:40 Música
drwxrwxr-x 2 hector hector 4,0K mar 27 14:40 Imágenes
drwxrwxr-x 3 hector hector 4,0K mar 27 14:41 R

Ahora veamos el contenido del directorio oculto .local ubicado en el home especificando la ruta absoluta:

ls /home/hector/.local
share

En el directorio .local solo existe el directorio share.

Ahora veamos el contenido del mismo directorio .local pero usando la ruta relativa desde el home:

ls .local
share

Como puede observar solo cambia el tipo de ruta que se pasa a ls pero el resultado es el mismo.

3.2.3 touch

Uso
touch [OPCIONES] ARCHIVO

Actualiza la fecha y hora de acceso y modificación de ARCHIVO a la hora actual. Si ARCHIVO no existe, touch creará el archivo vacío.

Generalmente touch se usa para crear archivos vacíos:

touch mi_archivo.txt

Como mi_archivo.txt no existe, touch lo crea. Verifiquemos con ls que mi_archivo.txt fue creado:

ls -lh --time-style +%H:%M:%S
total 48K
drwxrwxr-x 2 hector hector 4,0K 16:08:05 bin
drwxr-xr-x 6 hector hector 4,0K 19:43:33 Descargas
drwxr-xr-x 2 hector hector 4,0K 20:29:56 Documentos
drwxr-xr-x 2 hector hector 4,0K 17:28:15 Escritorio
drwxrwxr-x 2 hector hector 4,0K 14:40:26 Imágenes
drwxrwxr-x 9 hector hector 4,0K 14:38:56 mambaforge
-rw-rw-r-- 1 hector hector    0 10:22:40 mi_archivo.txt
drwxrwxr-x 2 hector hector 4,0K 14:40:26 Música
drwxr-xr-x 2 hector hector 4,0K 17:28:15 Plantillas
drwxrwxr-x 9 hector hector 4,0K 13:10:50 projects
drwxrwxr-x 2 hector hector 4,0K 14:40:26 Público
drwxrwxr-x 3 hector hector 4,0K 14:41:33 R
drwx------ 5 hector hector 4,0K 17:14:01 snap
Nota

Se usó la opción --time-style +%H:%M:%S con ls para que se muestre la hora (+%H), los minutos (%M) y los segundos (%S) en la hora de modificación de los archivos.

Ahora mi_archivo.txt aparece en el listado con tamaño de archivo 0 (vacío; columna 4).

Si usa touch nuevamente sobre el mismo archivo, se actualizará la hora de modificación pues el archivo ya existe previamente:

touch mi_archivo.txt
ls -lh --time-style +%H:%M:%S
total 48K
drwxrwxr-x 2 hector hector 4,0K 16:08:05 bin
drwxr-xr-x 6 hector hector 4,0K 19:43:33 Descargas
drwxr-xr-x 2 hector hector 4,0K 20:29:56 Documentos
drwxr-xr-x 2 hector hector 4,0K 17:28:15 Escritorio
drwxrwxr-x 2 hector hector 4,0K 14:40:26 Imágenes
drwxrwxr-x 9 hector hector 4,0K 14:38:56 mambaforge
-rw-rw-r-- 1 hector hector    0 10:22:45 mi_archivo.txt
drwxrwxr-x 2 hector hector 4,0K 14:40:26 Música
drwxr-xr-x 2 hector hector 4,0K 17:28:15 Plantillas
drwxrwxr-x 9 hector hector 4,0K 13:10:50 projects
drwxrwxr-x 2 hector hector 4,0K 14:40:26 Público
drwxrwxr-x 3 hector hector 4,0K 14:41:33 R
drwx------ 5 hector hector 4,0K 17:14:01 snap

Puede ver que la hora de modificación es más reciente (columna 5) que la mostrada cuando se verificó la creación del archivo.

3.2.4 cd

Uso
cd [DIRECTORIO]

Cambia el directorio de trabajo (change directory) a la ubicación especificada en [DIRECTORIO]. Si no especifica un directorio, por defecto cd cambiará la ubicación al directorio home del usuario.

Veamos algunos ejemplos del comando cd. Primero se verifica la ubicación actual con pwd:

pwd
/home/hector

Como pudo observar, cd no presenta en pantalla ningún resultado o mensaje asociado. El resultado solo se verifica consultado la ubicación actual, como en el anterior ejemplo con pwd. En Ubuntu Linux, también se puede ver la ubicación actual en el símbolo del sistema (ver Sección 2.3) justo después de los dos puntos (:), en este caso el home representado por ~:

hector@Ubuntu:~$

Ahora se cambia la ubicación con cd al directorio Descargas con cd usando la ruta relativa:

cd Descargas

Su prompt debería indicar ahora que su directorio actual es Descargas:

hector@Ubuntu:~/Descargas$
Nota

Como puede ver, la ubicación en el prompt siempre abrevia la ruta absoluta a su directorio home con ~.

Ahora, si verifica la ubicación con pwd obtendrá la ruta absoluta a Descargas:

pwd
/home/hector/Descargas

Usando cd sin especificar ningún directorio cambiará la ubicación al home:

# Se usa cd para ir al home
cd
# Se verifica la ubicación actual
pwd
/home/hector
Nota

Las líneas del anterior bloque de comandos que empiezan con el símbolo #, son comentarios. Los comentarios son líneas que nunca son ejecutadas por el shell, en este caso Bash, y que aportan información adicional sobre los comandos a ejecutar.

Al igual que con otros comando que reciben rutas como argumentos, cd también trabaja con rutas absolutas. En el siguiente ejemplo se cambia al directorio Documentos usando una ruta absoluta:

cd /home/hector/Documentos
pwd
/home/hector/Documentos

Ahora se cambia al directorio padre del directorio actual con ...

cd ..
pwd
/home/hector
cd /home/hector/Descargas

3.2.5 mkdir

Uso
mkdir [OPCIONES] [DIRECTORIO]

Crea un nuevo directorio con el nombre especificado por [DIRECTORIO].

Opciones útiles:

  • -p: Crea los directorios padre de la ruta si es necesario

Veamos algunos ejemplos del comando mkdir. Desde el home, se crea el directorio pruebas:

cd
mkdir pruebas

mkdir tampoco provee un mensaje después de crear un directorio, a menos que haya ocurrido un error. Se puede usar ls para verificar la creación del directorio:

ls
bin
Descargas
Documentos
Escritorio
Imágenes
mambaforge
mi_archivo.txt
Música
Plantillas
projects
pruebas
Público
R
snap

Si intenta crear un directorio que ya existe, obtendrá un error:

mkdir pruebas
mkdir: no se puede crear el directorio «pruebas»: El archivo ya existe

Se pueden crear varios directorios a la vez con mkdir:

mkdir pruebas2 pruebas/dir1 pruebas/dir2

Verifiquemos la creación del directorio pruebas2 en el home:

ls
bin
Descargas
Documentos
Escritorio
Imágenes
mambaforge
mi_archivo.txt
Música
Plantillas
projects
pruebas
pruebas2
Público
R
snap

Ahora verifiquemos la creación de dir1 y dir2 en pruebas:

ls pruebas
dir1
dir2

3.2.6 cp

Uso
cp [OPCIONES] ORIGEN DESTINO
cp [OPCIONES] ORIGEN DIRECTORIO

Copia un archivo/directorio especificado en ORIGEN a DESTINO, o múltiples ORIGEN(es) a DIRECTORIO.

Opciones útiles:

  • -r: Copia directorios recursivamente.

Copiemos el archivo mi_archivo.txt, creado anteriormente, al directorio pruebas:

cp mi_archivo.txt pruebas
ls pruebas
dir1
dir2
mi_archivo.txt

Ahora, intentemos copiar el directorio dir1 completo con su contenido usando la opción -r (copia recursiva) de cp. Primero se crea un archivo al interior de dir1:

touch pruebas/dir1/archivo2.txt
# contenido de dir1
ls pruebas/dir1
archivo2.txt

Ahora se copia todo el directorio dir1 a dir2:

cp -r pruebas/dir1 pruebas/dir2
# contenido de dir2
ls pruebas/dir2
dir1

El directorio dir1 dentro de dir2 debería contener a archivo2.txt:

ls pruebas/dir2/dir1
archivo2.txt

3.2.7 mv

Uso
mv [OPCIONES] ORIGEN DESTINO
mv [OPCIONES] [ORIGEN] DIRECTORIO
  • Uso 1: Renombra el archivo/directorio especificado en ORIGEN a DESTINO, o
  • Uso 2: mueve el(los) elemento(s) especificado(s) en [ORIGEN] a DIRECTORIO.

Veamos el primer uso de mv para renombrar el archivo mi_archivo.txt:

mv mi_archivo.txt archivo1.txt

Ahora verifiquemos el cambio de nombre:

ls
archivo1.txt
bin
Descargas
Documentos
Escritorio
Imágenes
mambaforge
Música
Plantillas
projects
pruebas
pruebas2
Público
R
snap

Efectivamente el archivo que aparece ahora es archivo1.txt.

Veamos ahora el segundo uso de mv para mover el archivo archivo1.txt al directorio pruebas:

mv archivo1.txt pruebas

Verifiquemos que archivo1.txt aparece dentro de pruebas:

echo "*** Verificando contenido de home ***"
ls ~
echo "*** Verificando contenido de pruebas ***" 
ls pruebas
*** Verificando contenido de home ***
bin
Descargas
Documentos
Escritorio
Imágenes
mambaforge
Música
Plantillas
projects
pruebas
pruebas2
Público
R
snap
*** Verificando contenido de pruebas ***
archivo1.txt
dir1
dir2
mi_archivo.txt
Nota

En el ejemplo anterior se usó por primera vez el comando echo. Este comando sirve para imprimir mensajes por pantalla. Es recomendable que siempre el texto del mensaje que se pasa a echo vaya entre comillas.

3.2.8 cat

Uso
cat [OPCIONES] [ARCHIVO]

Concatena el(los) archivo(s) especificados en ARCHIVO a la pantalla (salida estándar).

El comando cat es útil para leer archivos y mostrarlos en pantalla. Por ejemplo, veamos el contenido del archivo de configuración .profile que está en el home:

cat .profile
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
    fi
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
    PATH="$HOME/.local/bin:$PATH"
fi

Los archivos ocultos en Linux siempre tienen un punto (.) como primer carácter en el nombre. Para ocultar un archivo basta con anteponer un punto en el nombre. Para ver los archivos oculto con ls, se debe usar la opción -a (ls -a).

El archivo .profile del ejemplo anterior es un archivo de configuración vital para el funcionamiento de la línea de comandos. Este archivo permanece oculto para evitar la modificación o eliminación accidental. Absténgase de modificarlo a menos que sepa muy bien lo que hace.

Ahora veremos como imprimir dos archivos con cat, pero primero descarguemos los archivos. Para descargar los archivos ejecute la siguientes órdenes:

wget -O pruebas/ejemplo_01.fasta \
  https://raw.githubusercontent.com/hspitia/linux_example_files/main/ejemplo_01.fasta
wget -O pruebas/ejemplo_02.fasta \
  https://raw.githubusercontent.com/hspitia/linux_example_files/main/ejemplo_02.fasta
--2023-03-28 10:22:46--  https://raw.githubusercontent.com/hspitia/linux_example_files/main/ejemplo_01.fasta
Resolviendo raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.109.133, ...
Conectando con raw.githubusercontent.com (raw.githubusercontent.com)[185.199.111.133]:443... conectado.
Petición HTTP enviada, esperando respuesta... 200 OK
Longitud: 197 [text/plain]
Guardando como: “pruebas/ejemplo_01.fasta”

     0K                                                       100% 24,5M=0s

2023-03-28 10:22:47 (24,5 MB/s) - “pruebas/ejemplo_01.fasta” guardado [197/197]

--2023-03-28 10:22:47--  https://raw.githubusercontent.com/hspitia/linux_example_files/main/ejemplo_02.fasta
Resolviendo raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.109.133, 185.199.108.133, ...
Conectando con raw.githubusercontent.com (raw.githubusercontent.com)[185.199.110.133]:443... conectado.
Petición HTTP enviada, esperando respuesta... 200 OK
Longitud: 196 [text/plain]
Guardando como: “pruebas/ejemplo_02.fasta”

     0K                                                       100% 15,9M=0s

2023-03-28 10:22:47 (15,9 MB/s) - “pruebas/ejemplo_02.fasta” guardado [196/196]
Nota

En el ejemplo anterior se descargaron archivos desde la terminal usando el comando wget. Veamos las partes de uno de los comandos ejecutados:

  • wget: el nombre del comando para descargar el archivo
  • -O pruebas/ejemplo_01.fasta: Opción (-O) y nombre (path) con el cual queremos guardar el archivo a descargar
  • https://raw.githubusercontent.com/hspitia/linux_example_files/main/ejemplo_01.fasta: la dirección (URL) en la Internet del archivo que se descargará

Otro comando muy utilizado para descargar archivos es curl. Es recomendable que explore la ayuda de wget y curl para saber más sobre su uso y funciones.

Nota

En el ejemplo anterior el carácter \ (backslash) se usa al final de la línea para indicar que el comando continúa en la línea siguiente. Se usa cuando el comando es más largo (en caracteres) que el ancho de la terminal.

Verifiquemos ahora que los archivos fueron descargados en el directorio pruebas:

ls pruebas
archivo1.txt
dir1
dir2
ejemplo_01.fasta
ejemplo_02.fasta
mi_archivo.txt

Ahora, se imprime el contenido de los archivos descargados usando el comando cat:

cat pruebas/ejemplo_01.fasta pruebas/ejemplo_02.fasta
>Secuencia_01
CGAGTCAGCTGTCAGCTAGTCGATCGCGATATGCTATATCGTTCTTTCGATGCTACTTTA
TTCGCTGTAGAAAATGCTCGGCTTAGCTGATCGCTCGATCGACACGATGCATCGATGTTC
GCTAGTACGTACGTACGTACGCATCGATCGGCTAGCCTATATATCGGATCGATCGGATAA
>Secuencia_02
TTCGCCTCCCATTATGCTCGGCTTAGCTGATCGCTCGATCGACACGATGCATCGATGTTC
CGGGGCTAATCGATCCTAGCTAGCTCTATATTGCTATATCGTTCTTTCGATGCTACTTTA
GCTAGTACGTACGTACGTACGTAGATAGATTCGGCTATCGGTTATATAGGATTTATTAAA
Nota

El formato FASTA3 (.fasta), uno de lo más comunes en bioinformática, es un formato de solo texto, usado para almacenar una o más secuencias de ADN o de proteínas. Usualmente cuando se almacena más de una secuencia en un archivo, se denomina multifasta. Cada secuencia tiene dos partes: (1) el identificador, que consiste de una sola línea con el nombre de la secuencia y que debe iniciar con el símbolo > (p. ej. >Mi secuencia); y (2) la secuencia, que puede tener una o más líneas con los caracteres que representan la secuencia. Si la secuencia es de ADN, los caracteres representan nucleótidos4 (A, C, G, T o U), y si es de proteínas, representan aminoácidos5.

Cada archivo contiene cuatro líneas de texto (una empezando con > con el nombre de la secuencia, y tres con la secuencia de ADN). Como se pasaron los nombres de los dos archivos, cat imprime los contenidos uno seguido del otro sin ninguna separación visible, es decir los concatena.

3.3 Redirección de entrada y salida

La redirección de entrada y salida es un concepto poderoso de comunicación entre procesos, sumamente útil en la línea de comandos para crear archivos y construir pipelines (tuberías) de programas. Estos pipelines son fundamentales en bioinformática para procesar grandes cantidades de datos de manera automatizada. Para comprender mejor la redirección primero se deben entender los flujos estándar.

3.3.1 Flujos estándar

La entrada y salida de información en Linux está organizada en flujos (streams) estándar (std). Existen tres flujos estándar: (1) de entrada (in) llamado stdin que se encarga de llevar información hacia los programas o procesos; (2) de salida (out) llamado stdout que lleva información (o resultados) desde los programas hasta el usuario u otros programas; y (3) de error (error) llamado stderr que lleva información solo de errores desde los programas. Por defecto, la entrada estándar viene desde el teclado, y la salida y el error estándar son dirigidos a la pantalla (Figura 3.2). Cada flujo tiene asociado un número que lo identifica: 0 para stdin, 1 para stdout, y 2 para stderr.

Figura 3.2. Los flujos estándar de entrada (stdin), salida (stdout) y error (stderr) para un programa (proceso) ejecutado en una terminal de texto. Diagrama adaptado del artículo de Wikipedia “Redirection (computing)”.

3.3.2 Redirección de flujos

La redirección consiste en redirigir los flujos hacia otros destinos diferentes de los dispuestos por defecto. Para redirigir la salida se usa el carácter >, y para redirigir la entrada se usa <.

3.3.2.1 Salida

Cuando usa un comando, como ls, vemos el resultado por pantalla dado que este es el dispositivo de salida por defecto. Usemos entonces la redirección para enviar la salida de ls a un archivo en lugar de la pantalla:

ls > pruebas/salida.txt

Como se esperaba, el comando anterior no generó ninguna salida por pantalla y en cambio la escribió en el archivo pruebas/salida.txt. Si verificamos el contenido, observaremos que corresponde con la lista de los archivo y carpetas del directorio personal:

cat pruebas/salida.txt
bin
Descargas
Documentos
Escritorio
Imágenes
mambaforge
Música
Plantillas
projects
proyectos
pruebas
pruebas2
Público
R
snap
Vídeos

Ahora vamos a redirigir la salida del comando echo al archivo pruebas/salida.txt, y posteriormente mostrar su contenido:

# Se redirige la salida de echo
echo "Prueba de redirección 1" > pruebas/salida.txt

# Se muestra por pantalla el contenido
cat pruebas/salida.txt
Prueba de redirección 1

¿Qué pasó con el contenido del archivo? Ahora pruebas/salida.txt contiene solo la salida de echo; el contenido anterior (salida de ls) fue sobreescrito.

Para usar la redirección y evitar que el contenido del archivo sea sobreescrito, se debe usar el doble símbolo de redirección >>. Así se añade (append en inglés) al contenido del archivo:

# Se redirige la salida de ls añadiendo al archivo
ls >> pruebas/salida.txt

# Se verifica el contenido
cat pruebas/salida.txt
Prueba de redirección 1
bin
Descargas
Documentos
Escritorio
Imágenes
mambaforge
Música
Plantillas
projects
proyectos
pruebas
pruebas2
Público
R
snap
Vídeos

Ahora vemos que la salida de ls fue añadida al contenido previo.

3.3.2.2 Entrada

Podemos redirigir la entrada de un comando desde una fuente alternativa con <. Por ejemplo, en lugar de pasar a cat el nombre de archivo como un argumento, podemos usar la redirección:

cat < pruebas/salida.txt
Prueba de redirección 1
bin
Descargas
Documentos
Escritorio
Imágenes
mambaforge
Música
Plantillas
projects
proyectos
pruebas
pruebas2
Público
R
snap
Vídeos

Vemos que el resultado es el mismo con la redirección que pasando el archivo directamente.

En el anterior ejemplo no hay mucha utilidad adicional a parte de mostrar un ejemplo, sin embargo, la redirección de entrada es útil en otros casos como por ejemplo leer archivos línea a línea con un bucle o ciclo (loop en inglés) while:

while read line               
do                            
  echo "-> $line"             
1done < pruebas/salida.txt
1
Se pasa el archivo al bucle para que sea leído. Se usa la redirección de entrada (<)
-> Prueba de redirección 1
-> bin
-> Descargas
-> Documentos
-> Escritorio
-> Imágenes
-> mambaforge
-> Música
-> Plantillas
-> projects
-> proyectos
-> pruebas
-> pruebas2
-> Público
-> R
-> snap
-> Vídeos
Tip

En el ejemplo anterior se usó una estructura repetitiva, también llamada ciclo o bucle, while6. La finalidad de esta estructura es que se repitan una serie de acciones o comandos mientras (while en inglés) se cumpla una condición (sea verdadera). Veamos la estructura:

1while CONDICION
2do
3  ACCION_1
  ACCION_2
    ...
  ACCION_N
4done
1
Inicio del ciclo y condición. Se inicia siempre con while (mientras) y luego la condición. CONDICION es una expresión lógica, es decir que siempre representa un valor de verdadero (true) o falso (false). Siempre que la condición sea verdadera, las acciones se ejecutarán, es decir, el ciclo termina cuando la condición se vuelve falsa.
2
Inicio del bloque de acciones. Siempre se marca con do (hacer), el inicio de las acciones que se repetirán.
3
Las acciones a repetir. Las acciones (comandos) pueden ser una o muchas, e incluso otros ciclos (ciclos anidados).
4
Final del bucle. Se marca con done (hecho) el final de las acciones y del bucle en general.

En el ejemplo anterior la condición se hará verdadera siempre que hayan líneas en el archivo por leer, así que la primera línea se lee como “mientras se pueda leer una línea”. Aquí el comando read (leer) se encarga de leer una línea de texto y guardarla temporalmente en la variable line. La única acción que se ejecuta en el bucle anterior, es imprimir con echo el contenido de la línea de texto guardada en la variable line. Observe que para poder consultar (dereferenciar) el contenido de la variable se debe anteponer el símbolo $ ($line). También observe que se imprimieron los caracteres -> antes del contenido de cada línea; esto fue solo para cambiar un poco la apariencia de la salida de todo el comando. Finalmente, en el cierre del bucle se usa la redirección de entrada (<) para pasar al bucle el archivo que será leído. Este es un caso especial del bucle while muy útil para ejecutar acciones dependientes del contenido de un archivo.

3.3.3 Pipelines o tuberías

Uno de los mecanismos más útiles y poderosos de la redirección es el de los pipelines, pipes o tuberías, pues permiten la ejecución de múltiples programas o comandos de manera secuencial como si estuvieran conectados por una tubería (pipe en inglés). En los pipelines la salida de un programa es pasada directamente como entrada a otro programa usando el carácter | (barra vertical o pipe). La Figura 3.3 muestra un diagrama de un pipeline de tres programas y sus correspondientes flujos de entrada y salida.

Figura 3.3. Representación de los flujos de entrada/salida de un pipeline (tubería) de tres programas ejecutados en una terminal de texto. En un pipeline, la salida de un programa (stdout) es la entrada (stdin) para el siguiente programa. Diagrama adaptado del artículo de Wikipedia “Redirection (computing)”.

Veamos los pipes en acción. Supongamos que se desea saber cuántos archivos de texto (con extensión .txt) hay en el directorio pruebas. Esto se puede lograr con una combinación de los programas ls y wc conectados con un pipe. Primero intentemos listar solo los archivos de texto en pruebas:

ls pruebas/*.txt
pruebas/archivo1.txt
pruebas/mi_archivo.txt
pruebas/salida.txt

En el comando anterior, se usa ls para listar cualquier archivo (*) con extensión .txt que se encuentre en el directorio pruebas. En el resultado vemos que ls nos muestra tres archivos, imprimiendo uno en cada línea independiente.

Ahora se redirige la salida del anterior comando hacia el programa wc:

ls pruebas/*.txt | wc -l
3
Nota

En el ejemplo anterior se usó el comando wc7 (por word count) con el cual se cuenta el número de líneas, palabras, bytes, y caracteres en uno o más archivos. Específicamente se usó la opción -l que cuenta el número de líneas de un archivo, o como en este caso, de la entrada estándar que es la salida de ls.

En el ejemplo anterior se usa el símbolo | para redirigir la salida de ls como entrada del comando a la derecha, es decir wc. ls lista los tres archivos de texto y wc cuenta entonces el número de líneas que hay en la entrada, por esto wc retorna 3.

Tip

Para comprender mejor los pipelines se recomienda ejecutar cada parte por separado. Así verá los resultados intermedios de cada programa que quedan ocultos cuando se ejecuta el pipeline completo.

Veamos otro ejemplo. Una tarea muy común es contar el número de secuencias que hay en un archivo multifasta. Esto se puede lograr con los comandos grep y wc en un pipeline. Además, podemos agregar un nivel más en el pipeline si agregamos el comando cat:

cat pruebas/*.fasta | grep '>' | wc -l
2
Nota

En el ejemplo anterior se usó el comando grep8 que sirve para buscar contenido específico en uno o más archivos. grep es una herramienta poderosa que se basa en el uso de expresiones regulares9, las cuales son instrucciones especiales que representan patrones de búsqueda. Específicamente, se usó grep para buscar el carácter > en la entrada estándar (salida de cat).

Analicemos el pipeline. En la primera parte se usa cat para concatenar todos los archivos FASTA (*.fasta) que están en pruebas, tal como en el último ejemplo de la sección Sección 3.2.8. La salida de cat es entonces un conjunto de dos secuencias en formato FASTA. Después, la salida de cat se convierte en la entrada de grep por medio de | (pipe). En la segunda parte del pipeline, grep busca el carácter > e imprime solo las líneas de la entrada en las cuales hay una o más ocurrencias de ese carácter, es decir las dos líneas que corresponden a los nombres de las secuencias, que por regla, deben empezar con >. Luego, la salida de grep se convierte en la entrada para el programa wc usando de nuevo |. En la tercera y última parte, se cuentan las líneas de la entrada con wc -l, por lo que finalmente el resultado es 2.


  1. Permisos de archivos y directorios: https://www.linuxtotal.com.mx/index.php?cont=info_admon_011↩︎

  2. Wikipedia - Enlace duro: https://es.wikipedia.org/wiki/Enlace_duro↩︎

  3. Wikipedia - Formato FASTA: https://es.wikipedia.org/wiki/Formato_FASTA↩︎

  4. Wikipedia - Nucleótido: https://es.wikipedia.org/wiki/Nucle%C3%B3tido↩︎

  5. Wikipedia - Aminoácido: https://es.wikipedia.org/wiki/Amino%C3%A1cido↩︎

  6. Wikipedia - Bucle while: https://es.wikipedia.org/wiki/Bucle_while↩︎

  7. Wikipedia - wc (Unix): https://en.wikipedia.org/wiki/Wc_(Unix)↩︎

  8. Wikipedia - Grep: https://es.wikipedia.org/wiki/Grep↩︎

  9. Wikipedia - Expresión regular: https://es.wikipedia.org/wiki/Expresión_regular↩︎