Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

293
Vistas
analizar el resultado de `ls -l` con bash script

Necesito almacenar el nombre de cada archivo contenido en un directorio con un script bash y procesarlo de alguna manera:

 drwxrwxr-x 5 matteorr matteorr 4096 Jan 10 17:37 Cluster drwxr-xr-x 2 matteorr matteorr 4096 Jan 19 10:43 Desktop drwxrwxr-x 9 matteorr matteorr 4096 Jan 20 10:01 Developer drwxr-xr-x 11 matteorr matteorr 4096 Dec 20 13:55 Documents drwxr-xr-x 2 matteorr matteorr 12288 Jan 20 13:44 Downloads drwx------ 11 matteorr matteorr 4096 Jan 20 14:01 Dropbox drwxr-xr-x 2 matteorr matteorr 4096 Oct 18 18:43 Music drwxr-xr-x 2 matteorr matteorr 4096 Jan 19 22:12 Pictures drwxr-xr-x 2 matteorr matteorr 4096 Oct 18 18:43 Public drwxr-xr-x 2 matteorr matteorr 4096 Oct 18 18:43 Templates drwxr-xr-x 2 matteorr matteorr 4096 Oct 18 18:43 Videos

con el siguiente comando puedo dividir el resultado de ls -l entre todos los espacios y luego acceder al último elemento, que contiene el nombre:

 ls -l | awk '{split($0,array," ")} END{print array[9]}'

Sin embargo, solo devuelve la última línea (es decir, Videos ), por lo que necesito iterarlo sobre todas las líneas devueltas por el ls -l .

  • ¿Cómo puedo hacer esto?
  • ¿Hay una mejor manera de abordar todo este problema?

PARTE AÑADIDA

Para ser un poco más específico en lo que tengo que hacer:

Para todos los archivos contenidos en un directorio, si es un archivo, no haré nada, si es un directorio, debo agregar el nombre del directorio a todos los archivos que contiene.

Entonces supongamos que el directorio Videos tiene los archivos:

 -rwxr-xr-x 2 matteorr matteorr 4096 Oct 18 18:43 video1.mpeg -rwxr-xr-x 2 matteorr matteorr 4096 Oct 18 18:43 Video2.wmv

Necesito cambiarles el nombre de la siguiente manera:

 -rwxr-xr-x 2 matteorr matteorr 4096 Oct 18 18:43 video1_Videos.mpeg -rwxr-xr-x 2 matteorr matteorr 4096 Oct 18 18:43 Video2_Videos.wmv
over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Una mejor manera sería usar bash globbing

Solo listando todos los archivos

 echo *

O hacer algo con ellos.

 for file in *; do echo "$file" # or do something else done

O recursivamente con bash 4+

 shopt -s globstar for file in **/*; do echo "$file" # or do something else done

Actualizar para obtener el nombre del directorio y agregarlo a todos los archivos dentro de él

Reemplace mv con un echo para probar lo que hace. También tenga en cuenta que ${file##*.} asume que la extensión es todo después del último punto, por lo que si tuviera un archivo como file.tar.gz en el directorio on , debajo lo convertiría en file.tar_on.gz . Hasta donde yo sé, no hay una manera fácil de manejar este problema, aunque podría omitir archivos con múltiples . si tu quieres)

 #!/bin/bash d="/some/dir/to/do/this/on" name=${d##*/} #name=on for file in "$d"/*; do extension=${file##*.} filename=${file%.*} filename=${filename##*/} [[ -f $file ]] && mv "$file" "$d/${filename}_${name}.$extension" done

p.ej

 > ls /some/dir/to/do/this/on video1.mpeg Video2.wmv > ./abovescript > ls /some/dir/to/do/this/on video1_on.mpeg Video2_on.wmv

Explicación

En bash puedes hacer esto

  • ${parameter#word} Elimina el prefijo coincidente más corto
  • ${parameter##word} Elimina el prefijo coincidente más largo
  • ${parameter%word} Elimina el sufijo coincidente más corto
  • ${parameter%%word} Elimina el sufijo coincidente más largo

Para eliminar todo lo que sea ( * ) antes e incluido el último punto, lo hice a continuación

 extension=${file##*.}

Para eliminar todo, incluido y desde el último punto, lo hice a continuación (piense en la coincidencia más corta aquí de derecha a izquierda, por ejemplo, * busca cualquier texto que no sea de punto de derecha a izquierda, luego, cuando encuentra un punto, elimina toda esa sección )

 filename=${file%.*}

Para eliminar todo hasta el último / incluido, lo hice a continuación.

 filename=${filename##*/}

Algunas otras notas:

  • "$d/${filename}_${name}.$extension" Las variables pueden tener _ , así que cambié la sintaxis de un par de variables aquí para que funcione
  • "$d"/* expande a todos los archivos de cualquier tipo (regular, dir, enlace simbólico, etc.) directamente en "$d"
over 4 years ago · Santiago Trujillo Denunciar

0

Lo que está mal con

 ls > myfile.txt

Esto solo enumerará los nombres de los archivos (nada más) y los enviará a myfile.txt

Si quieres ir por la ruta awk , solo hazlo

 ls -l | awk '{print $9}'

La acción predeterminada de awk es dividir los campos en el espacio, y esto imprime el noveno campo para cada línea...

Si desea hacer otras cosas con los nombres de los archivos, simplemente puede extender su secuencia de comandos awk. Por ejemplo, se podría crear una matriz con estos nombres de archivo con

 ls -l | awk '{a[NR]=$9}'

y puede usar esta matriz (llamada a ) en el procesamiento posterior. Si el procesamiento requiere algo más que awk (por los comentarios, creo que sí), estaría mejor con algo que se parezca a

 #!/bin/bash for f in $1"/"* do if [ -d "$f" ] ; then ./listdir $f else echo $f fi done

Guarde esto como listdir en su directorio actual y listo.

 ./listdir .

Enumerará el directorio completo, recursivamente hacia abajo (con la ruta relativa completa adjunta) según sea necesario.

Si desea que esto esté disponible "desde cualquier lugar" (después de todo, es un comando bastante útil), lo colocaría en algún lugar de su camino (y haría un comando de "repetición" para que sea "conocido"); entonces no necesita el ./ al comienzo del comando.

over 4 years ago · Santiago Trujillo Denunciar

0

¡Buena pregunta! Me alegro de que hayas preguntado. Analizar la salida de ls rara vez es lo correcto. Hay innumerables formas de procesar una lista de archivos. Depende de lo que quieras hacer con ellos.

Estos son algunos ejemplos de cosas que puede hacer. He usado touch como un comando de ejemplo. Reemplace eso con cualquier comando o comandos que desee hacer.

  1. Para ejecutar un comando en varios archivos, a menudo puede simplemente pasar todos los archivos en la línea de comandos.

     touch /var/myapp/*
  2. Para recorrer los archivos en el directorio actual:

     for file in *; do touch "$file" done
  3. Para recorrer archivos en otro directorio:

     for file in /some/dir/*; do touch "$file" done
  4. Para cambiar el nombre de los archivos llamados *.txt a '*.bak', tanto aquí como en los subdirectorios:

     find . -name '*.txt' -exec mv {} {}.bak \;
  5. Para eliminar archivos JPEG en el directorio de inicio de Bob (maldito seas Bob y tus ojos errantes):

     find ~bob/ -name '*.jpg' -delete
  6. Para recorrer los archivos recursivamente y hacerles cosas complicadas:

     find /dir/to/search -print0 | while read -d $'\0' file; do echo "$file" touch "$file" if [[ -L $file ]]; then # $file is a symlink, do something special fi done
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda