Script en Bash

FraY_BrK

Hola a todos,

en primer lugar, decir que no escribo para que me hagáis los deberes, ya que ya tengo la solución, sino simplemente para preguntar más opciones, ya que me han dicho que me he enrollado mucho para obtener la solución y que puede conseguirse de una manera más corta.

Paso a describiros el problema:

Se trata de escribir un script en Bash que muestra cuantas extensiones diferentes hay en un directorio, junto con el número de ocurrencias de cada uno.

Es decir, que si tenemos 4 ficheros pdf y 3 txt, la salida mostrará pdf ---> 4, txt --->3

El "problema" está en que a priori, no se conoce el número de extensiones de fichero diferentes que existen.

Os presento el código comentado que he realizado yo y que realiza el proceso:

#!/bin/sh

exec 6>&1 #Hacemos una copia de la salida estandar con descriptor 6

exec 1> '/tmp/resultado.txt' #Redirigimos la salida estandar al fichero resultados.
ls |  
while read valor do if [ -f $valor ] then resul=$valor resul=${resul##*.} echo $resul fi done #Hemos filtrado todos los ficheros y nos hemos quedado con las extensiones, que es lo que nos interesa exec 1>&6 #Recuperamos la salida estandar exec 6>&- #Eliminamos el descriptor 6 sort /tmp/resultado.txt > /tmp/resultadosort.txt #Ordenamos el fichero de extensiones para tenerlas agrupadas rm /tmp/resultado.txt #Borramos el fichero intermedio #En este momento, tenemos en el fichero resultadosort.txt todas las posibles extensiones agrupadas por orden alfabético, #de forma que si recorremos el fichero leyendolos, podemos obtener la extensión y el número de apariciones existentes. paso=0 suma=0 for linea in `cat /tmp/resultadosort.txt` do if [ $paso -eq 0 ] then paso=1 extension=$linea ant=$extension suma=$(($suma+1)) else if [ $ant = $linea ] then suma=$(($suma+1)) else echo "Extension= $extension -----> Apariciones= $suma" extension=$linea ant=$extension suma=1 fi fi done echo "Extension= $extension -----> Apariciones= $suma" rm /tmp/resultadosort.txt

¿Se os ocurre alguna forma de realizarlo de forma más sencilla?

Un saludo y gracias!

LOc0

Por ejemplo:

#!/bin/sh

ls $1 -X | grep -E '^.+\.[^.]+$' | grep -o -E '[^.]+$' | awk '{w[tolower($0)]++} END{ print "Hay " length(w) " extensiones diferentes\n"; n=asorti(w,a); for (i=1;i<=n;i++) print a[i], "("w[a[i]]")"}'

Salu2 ;)

FraY_BrK

Perfecto LOc0, muchisimas gracias :)

Ulmo

Depende de para q clase sea no te dejaran usar awk

for i in `ls | grep "\."`; do echo ${i##*.}; done | sort | uniq -c
2 respuestas
LOc0

uniq -c +1 #4

Sin awk:

#!/bin/sh

a=`ls $1 -X | grep -o -E '\.[^.]+$' | uniq -c -i`
echo -e "Hay ["`echo "$a" | wc -l`"] extensiones distintas en $1\n$a"

Salu2 ;)

FraY_BrK

#4 En realidad vemos primero Bash, y luego Awk, pero no se puede mezclar en la primera parte, así que me quedo con las últimas opciones que habéis puesto.

Leyendo las soluciones, me parece que he reinventado la rueda y que debería mirarme más los comandos... jajaja

Usuarios habituales

  • FraY_BrK
  • LOc0
  • Ulmo