informatica:sol:laboratorio15:esercitazionia:bashscriptexamples

Alcuni esempi di script bash

toupper.sh

Stampa a video i nomi passati come argomento allo script contenenti lettere minuscole in nomi con tutte le lettere maiuscole.

#!/bin/bash

# es.  >$ toupper pippo Pluto MINNI
#         pippo --> PIPPO
#         Pluto --> PLUTO

# per ogni argomento  ($@ si può omettere)
for f in $@; do        
    # considero solo il nome e non eventuali path che lo precedono
    bname=`basename $f`
    # utilizzo tr per trasformare tutti i caratteri minuscoli in maiuscoli
    name=$(echo $bname| tr a-z A-Z)
    # se il nome conteneva lettere minuscole allora lo stampo sullo stdout
    if [ "$name" != "$bname" ]; then
	echo "$bname --> $name"
    fi
done

base2.sh

Dato un numero intero in base 10 come input stampa a video il numero in base 2.

#!/bin/bash

# es.  >$ base2.sh 11
#         11 --> 1011
#         

r=$(echo "obase=2; $1" | bc)
echo "$1 --> $r"

removeblanklines.sh

Data una lista di file testuali in input come argomenti dello script, rimuovere da ogni file le linee vuote.

#!/bin/bash

# se non ci sono argomenti stampo il messaggio di usage
if [ $#  -eq 0 ]; then
    echo "ERRORE: usa: `basename $0` lista-di-file" 1>&2 
    exit -1
fi
# per ogni argomento
for file in $@; do
    # controllo che sia un file regolare
    if [ ! -f $file ]; then
	echo "ERRORE, il file $file non esiste o non è un file regolare" 1>&2
	exit 1
    fi
    # controllo che sia scrivibile
    if [ ! -w $file ]; then
	echo "ERRORE, il file $file non e' scrivibile" 1>&2
	exit 2
    fi

    # rimuovo le linee bianche
    # ^ rappresenta l'inizio della linea
    # $ rappresenta la fine della linea
    $(sed -i '/^$/d' $file)

    if [ $? -ne 0 ]; then
	echo "ERRORE nella rimozione delle linee vuote nel file $file" 1>&2
	exit 3
    fi
done

include.sh

Realizzare uno script bash che preso come argomento un nome di file (il file può avere solo estensione “.c”o “.h”) verifica se il file contiene include C “locali” (cioè della forma #include “name.h”) e/o include C “globali” (cioe' della forma #include <name.h>).

#!/bin/bash

# es.  >$ include.sh prova.c
#         Il file "prova.c" contiene l'include globale: stdio.h
#         Il file "prova.h" contiene l'include locale:  prova.h

# se non ci sono argomenti stampo il messaggio di usage
if [ $# -eq 0 ]; then
    echo "ERRORE: usa: `basename $0` 'file'" 1>&2
    exit -1
fi
# controllo se il file in ingresso e' un file regolare
if [ ! -f $1 ]; then
    echo "ERRORE: il file $1 non esiste o non è un file regolare" 1>&2
    exit 1
fi

# controllo l'estensione del file (modo 1: utilizzando grep)
r=$(echo $1 | grep "\.[ch]")
if [ "$r" != "$1" ]; then
    echo "ERRORE: il file $1 non ha estensione .c o .h" 1>&2
    exit 2
fi
# controllo l'estensione del file (modo 2: utilizzando le espressioni regolari bash) 
if [[ ! $1 =~ .*\.[ch] ]]; then
    echo "ERRORE: il file $1 non ha estensione .c o .h" 1>&2
    exit 2
fi

# per ogni linea verifico se c'e' un match con una espressione regolare bash
while read line; do
    if  [[ $line =~ \ *#\ *include\ *\"(.*)\"\ * ]]; then
	echo "Il file \"$1\" contiene l'include locale:  ${BASH_REMATCH[1]}"
    else
	if [[ $line =~ \ *#\ *include\ *\<(.*)\>\ * ]]; then
	    echo "Il file \"$1\" contiene l'include globale: ${BASH_REMATCH[1]}"
	fi
    fi
done < $1

spaziodisco.sh (un esempio più complesso)

Data un nome di directory come argomento dello script, stampare sullo standard output la lista ordinata in modo decrescente (in base alla size) dei file/directory contenuti nella directory passata allo script, il tipo del file (F per file e D per directory) e la size in formato human readable.
Es: ./spaziodisco.sh /home

riccardo     D    15G
marta        D    9G
sara         D    6G
miofile      F    43K
#!/bin/bash

if [[ $# != 1 ]]; then
    echo "usa:" 1>&2
    echo "  `basename $0` directory" 1>&2
    exit 1
fi

if [ ! -d $1 ]; then
    echo "ERROR: $1 non è una directory" 1>&2
    exit 2
fi
if [ ! -r $1 ]; then
    echo "ERROR: la directory $1 non è leggibile" 1>&2
    exit 3
fi

# togliamo lo slash finale se c'e' (canonizzare)
# from http://tldp.org/LDP/abs/html/parameter-substitution.html
# ${var%Pattern} 
# Remove from $var the shortest part of $Pattern that matches the back end of $var. 
startdir=${1%/}

# creo una lista contenente l'output del comando du + sort
# sort -h ordina aspettandosi numeri in formato human readable 10K, 2G.....
data=( $(du -sh $startdir/* 2> /dev/null | sort -hr) )
# prendo il numero totale di elementi dalla lista 
ndata=${#data[@]} 

#scorro la lista prendendo le coppie <size, /startdir/dir> 
for((i=0;i<((ndata-1));i+=2)); do
    # suppongo che per default sia un file
    type=F
    # e' una directory ?
    if [ -d ${data[i+1]} ]; then
	type=D
    fi
    # prendo solo il nome
    name=`basename ${data[i+1]}`
    # faccio la stampa formattata usando printf (C-style)
    printf "%-30s\t%2s\t%-10s\n" $name $type ${data[i]}
done
informatica/sol/laboratorio15/esercitazionia/bashscriptexamples.txt · Ultima modifica: 16/03/2016 alle 11:22 (7 anni fa) da Massimo Torquati