Newsgroup: it.comp.os.linux.sys
Titolo: Bash script mac address

Ciao a tutti,
ho un problema riguardo un bash script che mi permette di suddividere un 
mac address con la punteggiatura :
 
esempio :
 
001e4aa8f451 ---> risultato finale 00:1e:4a:a8:f4:51
 
Considerando che questa operazione devo eseguirla su 300 mac address vi 
chiedo il vostro aiuto per semplificare questo script.
 
Grazie 1000
 
 
#/bin/bash
 
read a b c d e f g h i l m n o p q r s t u v z
echo ${a:0:2}:${a:2:2}:${a:4:2}:${a:6:2}:${a:8:2}:${a:10:2}
echo ${b:0:2}:${b:2:2}:${b:4:2}:${b:6:2}:${b:8:2}:${b:10:2}
echo ${c:0:2}:${c:2:2}:${c:4:2}:${c:6:2}:${c:8:2}:${c:10:2}
echo ${d:0:2}:${d:2:2}:${d:4:2}:${d:6:2}:${d:8:2}:${d:10:2}
echo ${e:0:2}:${e:2:2}:${e:4:2}:${e:6:2}:${e:8:2}:${e:10:2}
echo ${f:0:2}:${f:2:2}:${f:4:2}:${f:6:2}:${f:8:2}:${f:10:2}
echo ${g:0:2}:${g:2:2}:${g:4:2}:${g:6:2}:${g:8:2}:${g:10:2}
echo ${h:0:2}:${h:2:2}:${h:4:2}:${h:6:2}:${h:8:2}:${h:10:2}
echo ${i:0:2}:${i:2:2}:${i:4:2}:${i:6:2}:${i:8:2}:${i:10:2}
echo ${l:0:2}:${l:2:2}:${l:4:2}:${l:6:2}:${l:8:2}:${l:10:2}
echo ${m:0:2}:${m:2:2}:${m:4:2}:${m:6:2}:${m:8:2}:${m:10:2}
echo ${n:0:2}:${n:2:2}:${n:4:2}:${n:6:2}:${n:8:2}:${n:10:2}
echo ${o:0:2}:${o:2:2}:${o:4:2}:${o:6:2}:${o:8:2}:${o:10:2}
echo ${p:0:2}:${p:2:2}:${p:4:2}:${p:6:2}:${p:8:2}:${p:10:2}
echo ${q:0:2}:${q:2:2}:${q:4:2}:${q:6:2}:${q:8:2}:${q:10:2}
echo ${r:0:2}:${r:2:2}:${r:4:2}:${r:6:2}:${r:8:2}:${r:10:2}
echo ${s:0:2}:${s:2:2}:${s:4:2}:${s:6:2}:${s:8:2}:${s:10:2}
echo ${t:0:2}:${t:2:2}:${t:4:2}:${t:6:2}:${t:8:2}:${t:10:2}
echo ${u:0:2}:${u:2:2}:${u:4:2}:${u:6:2}:${u:8:2}:${u:10:2}
echo ${v:0:2}:${v:2:2}:${v:4:2}:${v:6:2}:${v:8:2}:${v:10:2}
echo ${z:0:2}:${z:2:2}:${z:4:2}:${z:6:2}:${z:8:2}:${z:10:2}
 

 chiedo il vostro aiuto per semplificare questo script.
 
Io mi sono sempre chiesto del perche' usare bash e rendersi la vita 
complicata quando il tutto si puo' fare con tre righe di perl o 
python... ;-)
 
Mauro


 
thò, una riga :P
 
 
MAC=001e4aa8f451
echo 
"${MAC:(-12):(-10)}:${MAC:(-10):(-8)}:${MAC:(-8):(-6)}:${MAC:(-6):(-4)}:${MAC:(-4):(-2)}:${MAC:(-2)}"
 
 
ok ok, è brutta. Però eccola :D
:)


Come ti già risposto Mauro chissà perchè complicarsi la vita:
 
echo '001e4aa8f451' | perl -pe 's/(\w\w)/:$1/g;s/^://'
 
 

 echo '001e4aa8f451' | perl -pe 's/(\w\w)/:$1/g;s/^://'
 
 
Grazie per la celere risposta e ottima risposta.
ma il mio problema è che ho più di 200 mac address da covenvertire :-(


scusa per l'"itagliano"

 ma il mio problema è che ho più di 200 mac address da covenvertire
 
Il bello dell'informatica è che puoi riciclare lo stesso comando a costo zero.
Seriamente non si capisce l'obiezione, ti hanno fatto vedere come 
convertirne uno, tu applichi lo stesso comando ad ognuna delle 200 
righe in ingresso e risolvi.
 
-- 
Andrea
 

Il 28/08/2013 16.41, Smith ha scritto:

metti tutti i mac in un bel file mac.txt
001e4aa8f451
001e4aa8f452
001e4aa8f453
etc..
 
fai uno script e chiamalo come vuoi
 
#!/bin/bash
COUNTER=1
TOTLINE=$( cat mac.txt | wc -l )
while [ $COUNTER -le $TOTLINE ]; do
	MAC=$( cat mac.txt | sed -n $COUNTER\p )
	echo '$MAC' | perl -pe 's/(\w\w)/:$1/g;s/^://' >> mac_output.txt
let COUNTER=COUNTER+1
done
 
 
dai i permessi +x e avvia lo script
 
 
intendiamoci, ci sono mille modi migliori e meno grezzi.


Non serve rendere il tutto cosi complicato
Lo script perl da me presentato legge già piu righe da stdin (è l' 
opzione 'p' di perl)
 
Quindi basta un semplice
 
perl -pe '...' < mac.txt
 
 

 opzione 'p' di perl)
 
 
e non lo sapevo :)


L' opzione p è un modo coinciso di eseguire un loop su stdin e per ogni 
riga scrivere il contenuto di una variabile speciale chiamata $_ su stdout
 
L' opzione n è uguale p tranne che non scrive su stdout
 
Per molte cose, quando la bash diventa troppo farraginosa, preferisco 
usare perl,ben piu flessibile e potente
 
 

 ;-)
 
O magari basta anche sed:
 
$ cat /tmp/file
001e4aa8f451
004455aa7711
001e422acd3d
 
$ sed -n 's/../&:/g;s/\(.*\):/\1/p' </tmp/file
00:1e:4a:a8:f4:51
00:44:55:aa:77:11
00:1e:42:2a:cd:3d
-- 
Bye, Lem
Ceterum censeo ISLAM esse delendum
_________________________________________________________________
Non sprecare i cicli idle della tua CPU, né quelli della tua GPU.
 
http://www.worldcommunitygrid.org/index.jsp
 
http://www.rnaworld.de/rnaworld/
 
http://home.edges-grid.eu/home/
 
 
http://www.gpugrid.net/
 


Scusa, ma non lo hai appena scritto qui sopra il programma?
 
Basta che cambia la "read a b ..."
 
con
 
while read a
do
  echo ...
done < mac_file.txt
 
Supponendo che il MAC address siano in un file.
 
Non hai specificato dove si trovano.
 
bye,
 
-- 
 
piergiorgio

 bye,
 
Li copiavo nella shell.

 perl -pe '...' < mac.txt
 
Ho modificato il tuo script per ulteriori prove ma mi da il "." dopo la 
conversione :-(
 
 
Esempio :
 
perl -pe 's/(\w\w\w\w)/.$1/g;s/^://' < mac.txt
 
 
.9caf.ca85.d1ff
.aca0.16fc.1b7f
.b4a4.e3d6.1286
.b4a4.e3d6.135f
.b4a4.e3d6.14db
.c8f9.f968.4e89
.c8f9.f968.4fce
.c8f9.f968.5359
.c8f9.f968.a525
.c8f9.f968.cbc7
.c8f9.f969.4a0e
.c8f9.f969.4a70
.e840.40a3.8071
.ecc8.8210.4ed4
.ecc8.8211.2190
.f025.7279.58cd
.ecc8.8211.2190
.f025.7279.58cd
 
 
 
 


Se gli dici di convertire in .$1 per forza che ti mette il punto
Metti :$1
 
 
 
 
 
 

 Li copiavo nella shell.
 
Cosa vuol dire questa frase?
 
bye,
 
-- 
 
piergiorgio

 Cosa vuol dire questa frase?
 
Io l'ho interpretata come copiare i valori e incollarli nell'emulatore 
di terminale come argomenti dello script. Ovviamente a 21 alla volta 
dato che ha usato la read con l'alfabeto italiano.
 
-- 
Andrea
 

 
 
OK, se questa interpretazione e` corretta, allora
anche lo script con una singola read funziona.
 
bye,
 
-- 
 
piergiorgio

 dato che ha usato la read con l'alfabeto italiano.
 
da principiante ;-)


solo una nota... se vogliamo essere pignoli (ma neanche tanto): questa è 
una regex perl + shell + tool di sistema (echo è un tool di sistema e pipe 
è specifico delle shell Unix). 
Fallo TUTTO in perl/python, supposto che tu prendi l'output da un file e 
lo scrivi su un altro. 
Quindi niente redirect, cat, tee, os.system("xxx") .. e vediamo fino a che 
punto perl/python "semplificano" le cose. 
devi aprire un file in scrittura, uno in lettura, se tutto va bene non 
importi librerie, poi usi l'algoritmo tipo quello sopra... ecco che in 
realtà non hai semplificato niente. 

 001e4aa8f451 ---> risultato finale 00:1e:4a:a8:f4:51
 
supponiamo che tu abbia un file di input contentente i Mac e supponiamo 
che il file si chiami: input.txt
 
cat input.txt|cut --output-delimiter=: -b"1-2 3-4 5-6 7-8 9-10 11-12"
 
 
Non è vero che i linguaggi (python/perl) semplificano la vita. I linguaggi 
si usano (e li uso pure io) perché sono più estesi e perché hanno moduli 
specifici per ogni sorta di operazione. Ma nella vita di tutti i giorni, 
un semplice task è più semplice da realizzare tramite una combinazione di 
shell + tool di sistema. 
cat e cut sono due tool di sistema. La pipe è specifica della shell Unix.


Infatti! Perché complicarsi la vita con 3 righe di perl, quando puoi fare 
tutto con una sola riga di shell + tool Linux:
cat input.txt |cut --output-delimiter=: -b"1-2 3-4 5-6 7-8 9-10 11-12"
 
Che poi si possa fare bene e meglio con python, non me lo dire perché lo 
so. Ma non è sempre questo il campo di utilizzo dei linguaggi. 


Chissà perchè bisogna usare un solo linguaggio proprio non lo capisco
La shell è fatta apposta per fare da collante, i professionisti non si 
mettono certamente a fare i talebani sugli strumenti da usare
 
 
 
 

 cat input.txt |cut --output-delimiter=: -b"1-2 3-4 5-6 7-8 9-10 11-12"
 
Che bello l'output-delimiter di cut! E io che nemmeno lo conoscevo! :'(
 
Se levi quel "cat abuse", raggiungi la perfezione. ;-p



per carità... però la soluzione di seguito non mi pare farraginosa:
 
cat input.txt|cut --output-delimiter=: -b"1-2 3-4 5-6 7-8 9-10 11-12"
 
ammetto che in altri casi potrebbe comunque risultare farraginoso... ma 
non era questo il caso ;)


Infatti il discorso era generico, non riferito necessariamente a questo 
caso
 
 

cat input.txt |cut --output-delimiter=: -b"1-2 3-4 5-6 7-8 9-10 11-12"
 
Non ti serve neanche il pipe:
 
	cut --output-delimiter=: -b"1-2 3-4 5-6 7-8 9-10 11-12" input.txt
 
Leonardo
 
-- 
 
Then felt I like some watcher of the skies, when a new planet swims into his ken;
Or like stout Cortez when with eagle eyes, he star'd at the Pacific; and all his men
Look'd at each other with a wild surmise - silent, upon a peak in Darien.

 Se levi quel "cat abuse", raggiungi la perfezione. ;-p
 
Piu semplice ancora essendo stringa a lunghezza fissa...
 
$ cut -c 1,2,4,5,7,8,10,11,13,14 input.txt
 
-- 
Flavio Visentin
 
Scientists discovered what's wrong with the female brain: on the left
side, there's nothing right, and on the right side, there's nothing left

 $ cut -c 1,2,4,5,7,8,10,11,13,14 input.txt
 
Forse volevi scrivere un'altra cosa, perché questo non funge. Quello di 
Leonardo è giusto. 


No, solo che sono stanco e facevo l'operazione inversa, da Mac :
separated a mac senza delimitatori...
Devo tornare in ferie.
