giovedì 31 luglio 2014

Contiamo le vocali [Brevi Esercizi]

Salve!

L'esercizio di oggi consiste in questo: Dato un file di testo, dobbiamo creare uno script che calcoli il numero di ciascuna vocale. Ho provato con bash, awk e Python.

Partiamo da questo file di testo (file.txt)


Python

#!/usr/bin/python
# -*- coding: utf-8 -*-

var = open("file.txt").read().lower()
vocali="aeiou"
for v in vocali:
        print  v, ": ", var.count(v)


Awk

#!/usr/bin/awk -f

BEGIN{
      c=split("aeiou",v,"")
      } 
      
{
  testo=tolower($0); 
  for (i=1;i<=c;i++) 
       print v[i] ": " gsub(v[i],"",testo)
}


Bash

cat file.txt |  fold -w1 | tr '[A-Z]' '[a-z]' | grep '[aeiou]' | sort | uniq -c | rev


Oppure, come propone il mio amico Lightuono,

grep -oi '[aeiou]' file.txt | sort | uniq -ic



Indice della rubrica "Brevi Esercizi" qui

martedì 29 luglio 2014

Imparare l'E-book [Cosa stai aspettando?]

Salve!

Oggi nasce una nuova rubrica: "Cosa stai aspettando?"

In questo spazio vi vogliamo parlare, di volta in volta, di piccoli capolavori scritti per lo più da carissimi amici. Si può trattare di E-book, libri cartacei, che abbiano a che fare con GNU/Linux, programmazione, formati liberi, ma anche romanzi, saggi e tutto ciò che riteniamo bello e assolutamente valido, indipendentemente dal fatto che siano gratis o a pagamento.

Oggi vi parliamo di "Imparare l'E-book". Si tratta di "un manuale autoprodotto che non promette la Luna, ma che vi aiuta a capire in quale parte del cielo guardare per vederla..."(Citazione di Flaminia, una delle autrici).


È un manuale che vi insegna a capire le differenze tra "formati proprietari" e "formati standard", a vedere cosa c'è dentro un file epub, ma anche a capire quale dispositivo sia meglio usare per "leggere un e-book" e dove trovare e scaricare e-book gratuiti per iniziare a prendere confidenza con questa splendida opportunità del mondo ICT.

Il manuale delle care amiche Flaminia Mancinelli e Marinella Zetti lo potete trovare in vari formati (epub, mobi e pdf) sul seguente sito  http://www.nidodellafenice.it/e-book/catalogo-nido-della-fenice/imparare-l-e-book-detail  oppure sui principali Bookshop online (da Amazon a Ultimabooks, passando per iTunes o IBS).

Buona lettura! Alla prossima :)

venerdì 18 luglio 2014

Underscore [Brevi Esercizi]

Salve.

L'esercizio di oggi consiste nell'aggiungere l'underscore, "_", ai titoli di alcune canzoni riportati in un file di testo. 


Python

#!/usr/bin/python
# -*- coding: utf-8 -*-

var = open("brani_1.txt","w")
for line in open('brani.txt'):
    var.write(line.replace(' ','_'))
var.close()


Awk

cat brani.txt | awk '{ gsub(" ","_"); print; }' > brani_1.txt

Sed

cat brani.txt | sed 's/ /_/g' > brani_1.txt

Tr

cat brani.txt |  tr ' ' '_' > brani_1.txt

Bash

var=$(cat brani.txt); echo "${var// /_}" > brani_1.txt

Alla prossima!

L'indice della rubrica "Brevi Esercizi" lo trovate qui.

mercoledì 16 luglio 2014

Creare una directory e 24 sottodirectory con date sequenziali in un solo colpo [Brevi Esercizi]

Salve!

L'esercizio di oggi è semplice ma molto utile. Ho l'abitudine di catalogare, per anno e mese, tutti gli articoli che pubblico sul blog. L'ideale in questi casi è  di creare sin da subito le sottocartelle datate dentro cui poi conservare i vari file afferenti ai post che pubblico di volta in volta.

Ok, vado al dunque.

Con una sola riga di comando voglio creare una cartella di nome "Blog" che contenga 24 sottocartelle, ognuna delle quali deve avere per nome l'anno e il mese.

$ cd Documenti

$ mkdir -p Blog/{2013..2014}-{01..12}

Come potete capire, ho preso come periodo di riferimento il 2013 e il 2014.

Ecco il risultato.


 Eh, questa è la potenza dell'espansione delle parentesi graffe... Ne parleremo presto in modo approfondito.

 L'indice della rubrica "Brevi Esercizi" lo trovate qui.

Alla prossima!

martedì 15 luglio 2014

In vacanza con bash

Vabbè, un titolo di consolazione. Quest'anno niente vacanze. E allora mi illudo di partire. Con il treno.

Per andare in vancanza con bash, anzitutto bisogna installare due piccoli pacchetti.

$ sudo apt-get install sl figlet

Non vi resta che eseguire lo script. E buon viaggio!

Salvatelo in un file di testo, vacanza.sh, e rendetelo eseguibile:

$ chmod +x vacanza.sh

non vi resta che eseguirlo

$ ./vacanza.sh

#!/bin/bash

fine() {
 testo="By Bit3Lux The End"
 for i in $testo; do 
     figlet -ct "$i"
     sleep 1
     clear 
 done
 exit 0
}
count=5
 while [ $count -ge 0 ]; do 
     clear 
     figlet -ctf shadow $count
     let count-=1 
     sleep 1 
 done
clear
read -p "Premi invio per far partire il treno. " 
partenza=0
while [ $partenza -le 6 ] ; do 
      clear;  
      sl -alFe; 
      clear
      let partenza+=1
      if [ "$partenza" -eq 5 ]; then
          read -p "premi 1 se vuoi continuare, premi 2 se ti vuoi fermare: " continuo
          if [ $continuo -eq 1  ]; then
              partenza=0
          else
             clear
             fine
          fi
      fi
done

Cosa fa lo script:
  1. Inizia con un countdown.
  2. Vi chiede di far partire il treno
  3. Ogni viaggio dura 5/6 secondi
  4. Vi chiede se volete fermarvi o continuare il viaggio
  5. Saluti finali.

Alla prossima! ;)

domenica 13 luglio 2014

Sub(), Gsub() e Gensub() [awk]

Salve. Oggi iniziamo con la rassegna delle funzioni predefinite di (G)awk

Cominciamo con le funzioni di sostituzione, cioè con sub(), gsub() e gensub(), che ci permettono di sostituire una stringa con un'altra all'interno di un testo.

La differenza tra sub() e Gsub() è che mentre sub() sostituisce solo la prima occorrenza, gsub() ha una portata globale.

Gensub() invece ci dà la possibilità di stabilire quale occorrenza sostituire.

Per una questione di comodità assegniamo il nostro testo ad una variabile.

testo="Linux è il bene. Linux è il bene. Linux è il bene."

Sub()

Nel nostro primo esempio chiediamo ad awk di sostituire solo prima occorrenza "Linux" con "GNU/Linux".

$ echo "$testo" | awk '{ sub("Linux","GNU/Linux"); print; }'

Output:

GNU/Linux è il bene. Linux è il bene. Linux è il bene.

Con sed invece si fa così:

$ echo "$testo" | sed 's/Linux/GNU\/Linux/'

Output:

GNU/Linux è il bene. Linux è il bene. Linux è il bene.

Gsub()
 
In questo esempio chiediamo ad awk di sostituire tutte le occorrenze Linux con GNU/Linux.

$ echo "$testo" |  awk '{ gsub("Linux","GNU/Linux"); print; }'

Output:

GNU/Linux è il bene. GNU/Linux è il bene. GNU/Linux è il bene.

Con sed si fa così:

$ echo "$testo" | sed 's/Linux/GNU\/Linux/g'

Outuput:

GNU/Linux è il bene. GNU/Linux è il bene. GNU/Linux è il bene.


Gensub()

Nell'esempio sotto chiediamo ad awk, attraverso la funzione gensub(), di sostituire solo l'occorrenza che decidiamo noi. Nell'esempio chiediamo di sostituire la terza occorrenza "Linux" con GNU/Linux

$ echo "$testo" | awk '{ $0=gensub("Linux","GNU/Linux", 3); print; }'

Outuput:

Linux è il bene. Linux è il bene. GNU/Linux è il bene.

Con sed si fa così:

$ echo "$testo" | sed 's/Linux/GNU\/Linux/3'

Output:

Linux è il bene; Linux è il bene; GNU/Linux è il bene.

E se volessimo sostituire tutte le occorrenze, diverse tra loro, presenti in una riga, con la stringa GNU/Linux?

Definiamo la nostra solita variabile, sempre per comodità di esposizione.

testo1="Windows, Mac, Solaris"

$ echo "$testo1" | awk '{ gsub(/Windows|Mac|Solaris/, "GNU/Linux"); print }'

Output:

GNU/Linux, GNU/Linux, GNU/Linux


Con sed invece si fa così:

$ echo "$testo1" | sed 's/Windows\|Mac\|Solaris/GNU\/Linux/g'

Output:

GNU/Linux, GNU/Linux, GNU/Linux

Indice del corso "Un po' di AWK", qui.

Alla prossima!

sabato 12 luglio 2014

Come passare una variabile da bash ad awk.

Il corso di awk è fermo da tempi immemorabili. Mi rendo conto che urge una sorta di sintesi e poi penso sia necessario partire quasi subito.

Oggi una curiosità, che in alcuni casi si rivela di importanza estrema: Come passare una variabile da bash ad awk.

Poniamo che in uno script si abbia una determinata variabile, ad esempio, $NUMERO, che contenga come valore "144". Per passarla ad awk bisogna fare così:

Posto che

NUMERO=144

si deve scrivere, più o meno (nel senso che il mio caso è solo un esempio)

awk -v number=$NUMERO 'BEGIN{print number}'

Questo discorso vale anche per le variabili interne di bash, come $USER, $HOME, $PATH, etc...

awk -v user=$USER 'BEGIN{print user}'

Alla prossima!

P.S. Altri articoli su awk potete trovarli qui e qui.

Costruiamo una calcolatrice [Brevi Esercizi]

Oggi costruiamo una semplice ma potente calcolatrice.

Partiamo dal risultato finale:

calcolatrice(){ awk "BEGIN{ print $* }" ;}

Da questa semplice (si fa per dire) riga di codice ne possiamo trarre gli ingredienti per poterla costruire.

Anzitutto c'è una funzione, la cui sintassi è la seguente:

calcolatrice() { comandi; }

Il comando della funzione (ne può contenere vari, eh), è costituito in questo caso da awk. Ad awk chiediamo di stampare il contenuto della variabile $*

$* è un parametro speciale. Possiamo dire che è una variabile il cui contenuto è costituito da ciò che noi diamo in pasto allo script a mo' di parametri posizionali.

Un esempio di parametri posizionali per la nostra calcolatrice può essere 5 + 6, che print di awk, essendo perspicace, riconosce come operazione aritmetica, e la svolge.

Ricordo che la funzione altro non è che del codice inerte, che diventa "vivo" solo quando viene richiamata, la funzione, col suo nome.

Se digitiamo il codice di cui sopra nel terminale, non succede un bel nulla. E il fatto che non succeda nulla vuol dire che il codice è scritto secondo la sintassi giusta.

Facciamo una prova, digitiamo il codice della nostra calcolatrice nel terminale:

calcolatrice(){ awk "BEGIN{ print $* }" ;}

Ora per richiamarla basta digitarne il nome seguito dall'operazione aritmetica che vogliamo svolgere. Esempio

calcolatrice 5+6

oppure

calcolatrice 5/6

Da quest'ultima operazione potrete notare come la nostra calcolatrice supporta benissimo i numeri decimali. Ben sei numeri dopo la virgola!!

La calcolatrice è pronta, tuttavia...

Tuttavia se chiudete il terminale, lo riaprite e richiamate la funzione con la vostra operazione da svolgere, vi viene restituito:

calcolatrice: comando non trovato

Essì, reset!!! Per evitare di scrivere ogni volta il codice della nostra calcolatrice dobbiamo riportarlo anche nel .bashrc, che si trova nella home dell'utente.

Abbiamo due modi per farlo. Andare a cercare il file .bashrc e incollare il codice di cui sopra, alla fine del testo, oppure costruire una riga di comando che faccia il lavoro sporco al posto nostro. Da lanciare una sola volta, eh! Infatti ">>" andrà ad "appendere" il codice della nostra calcolatrice nel file .bashrc.

echo "calcolatrice(){ awk \"BEGIN{ print \$* }\" ;}" >> ~/.bashrc


Di questa riga colpiscono i tre "\" (backslash). Uno serve a conservare il parametro speciale, che altrimenti sparirebbe. Gli altri due servono a mantenere i doppi apici al codice di awk. Provate a toglierli tutti e tre e vedete cosa succede.


Un'ultima cosa. Anche dopo aver aggiunto la riga di codice all'interno del file .bashrc, se provate a richiamare la calcolatrice, essa ancora non funziona. In realtà fin quando il terminale non verrà chiuso, non si accorgerà della modifica, a meno che...

A meno che non digitiamo:

source ~/.bashrc

Ecco, provate. E alla prossima.

 Altri articoli della rubrica "Brevi Esercizi" li trovate qui.

lunedì 7 luglio 2014

Una cosa sugli arrays [bash]

Si erano fatte le tre di notte e stavo seguendo un video in tedesco, fattomi pervenire per posta da un mio caro amico da Köln. Un corso di bash in tedesco, per intenderci. Tutto bene fino a quando il tale, che tra l'altro con il suo suono gutturale della voce mi ha stimolato i succhi gastrici, si è espresso in questi termini, più o meno:

definiamo un array:

$ valori=(1 2 3 4 5 6 7 8 9)

Ora, secondo lui, cioè il tale di cui sopra, se faccio

$ echo ${valori[*]}

$ echo ${valori[@]}

dovrei ottenere lo stesso risultato. Ed è proprio così. Ottengo tutti i valori dell'array. Ma non è questo il punto. Dai, questa cosa la sapevamo...

Mi sono detto, possibile che questi due caratteri, "@" e "*", non abbiano alcuna differenza in codesto ambito?

In realtà sì, una differenza l'ho scovata, forse. Magari ce ne sono pure altre.

$ for i in "${valori[*]}"; do echo " $i "; done #con i doppi apici

0 1 2 3 4 5 6

$ for i in ${valori[*]}; do echo " $i "; done #Senza doppi apici


 0
 1
 2
 3
 4
 5
 6

Mentre nel caso del carattere @,

$ for i in ${valori[@]}; do echo " $i "; done #senza doppi apici
$ for i in "${valori[@]}"; do echo " $i "; done #con i doppi apici

ottengo sempre, come risultato,

 0
 1
 2
 3
 4
 5
 6

Sicuramente i miei cari amici Ennio e Juhan ne sapranno di più.
 
Chi volesse approfondire gli arrays in bash, segnalo l'indice del progetto bash, qui.

sabato 5 luglio 2014

Pari o dispari [bash]

Salve!

Oggi un esercizio facile facile. 

Come faccio a far riconoscere a bash se un numero è pari o dispari?

Assegno alla variabile n il numero in questione:

$ n=141

poi divido la variabile n per due e ne assegno il risultato alla variabile n1

$ n1=$[$n/2]

Il risultato che viene assegnato alla variabile n1 lo moltiplico per 2 e ne assegno a sua volta il risultato alla variabile n2

$ n2=$[$n1*2]

E ora passiamo alla verifica.

$ test $n -ne $n2 && echo dispari || echo pari

Ora facciamo un piccolo script che ci chiede un numero e ci restituisce come risposta se è pari o dispari.

#!/bin/bash

read -p "dammi un numero: " n
n1=$[$n/2] 
n2=$[$n1*2]
test $n -ne $n2 && echo "$n è dispari" || echo "$n è pari"
exit 0

Semplice, no? :)

Alla prossima.

P.S. L'indice della rubrica "Brevi Esercizi" qui.