File UTF-8 con BOM

Verifica e pulizia di file con BOM

Si può riconoscere la presenza del BOM (Byte Order Mark)in un file con il comando

file file_con_bom.txt
file_con_bom.txt: UTF-8 Unicode (with BOM) text, with CRLF line terminators

In questo caso si può attuare una pulizia del creando un nuovo file

awk '{if(NR==1)sub(/^\xef\xbb\xbf/,"");print}' \
file_con_bom.txt > file_senza_bom.txt

o correggere direttamente il file

sed -i '1 s/^\xef\xbb\xbf//' file_con_bom.txt

File con ctrl-M (^M)

Toglie i CTRL-M da un file importato male (like il dos2unix)

Da riga di comando

cat $FILE_CTRL_M | tr -d '\r'> $FILE_SENZA_CTRL_M

oppure on-fly con il comando

perl -p -n -i -e "s/\r//" $FILE_CTRL_M

All’interno del vi, per ottenere il carattere ^M premere ctrl-v e ctrl-m, il comando di sostituzione eliminerà tutte le occorrenze del carattere.

:s/^M//g

Il mio file ha i ctrl-M?

Testiamo se un file di testo è in formato Unix o Dos:

$ cat dos.txt | od -c| tr -d ' '| grep -q '\\r\\n'
$ echo $?
0
$ cat unix.txt | od -c| tr -d ' '| grep -q '\\r\\n'
$ echo $?
1

Cerca tutti i file con ctrl-M

Definisce il carattere da cercare e esegue il find, una volta trovati i file si può applicare su di essi uno dei precedenti metodi per la pulizia dei ^M, come nell’esempio successivo

CHR13=`echo "x" | awk '{ printf "%c\n",13;}'`

find . -type f -exec grep -l $CHR13$ {} \;

Pulizia massiva dei file con CTRL-M

Cerco in tutti i file con estensione .sh e verifico ed elimino i terminatori di riga ^M

CHR13=`awk 'BEGIN{ printf "%c",13;}'`
find . -type f -name \*.sh -exec grep -l ${CHR13}$ {} \; | \
while read FILE_CTRL_M
do
    echo "Converting : ${FILE_CTRL_M}"
    sed -i 's/\r//g' ${FILE_CTRL_M}
done

Esecuzione in background

Lancio di un processo in background

Si può eseguire in background un processo aggiungendo il carattere & alla fine della stringa di comando:

sleep 10 &

Se il comando è lanciato dalla shell riapparirà il prompt, se invece è lanciato da uno script verrà eseguito il comando successivo dello script. Se si vuole imporre allo script di attendere la terminazione dei lanci in background (processi figli) si userà il comando wait:

comando1 &
comando2 &
wait

Spostare in background l’esecuzione di un processo

dopo aver lanciato un comando da terminale premere CTRL-Z

sleep 10
^Z
[1] + Stopped (SIGTSTP)        sleep 10

Il processo è ancora running ma fermo e il prompt è disponibile

ps -ef | grep sleep
   xuser 19578 27951   0 10:10:10 pts/4       0:00 sleep 10
   xuser 19583 27951   0 10:10:19 pts/4       0:00 grep sleep

Faccio procedere l’esecuzione in background:

bg 19578
[1]     sleep 10&

Il prompt ritorna disponibile ancora e al termine dell’esecuzione in background compare il messaggio:

[1] +  Done                    sleep 10

Customizzazione della shell

Una raccolta di bei prompt

Prompt a colori semplice

PS1=`echo "\033[36m"`'$PWD/'`echo "\033[0m\033[31m\n\r"`'# '`echo "\033[0m"`


Prompt a colori semplice.jpg

Prompt a colori complesso

PS1=`echo "\033[36m"`'$PWD/'`echo "\n\033[35m{\033[32m"`\
`date +'%H:%M:%S %d/%m/%Y'`\
`echo "\033[35m}\033[0m\033[31m\n\r"`' # '`echo "\033[0m"`


Prompt a colori complesso.jpg

Prompt a colori funzionale

PS1="\033[0;33m[\033[0;31m\u\033[0;30m:\033[0;31m\h\033[0;33m]\033[0m "\
"\033[0;36m\w\033[0;30m\n\033[0;35m#\033[0m "


Prompt a colori funzionale.jpg

Il tasto backspace non funziona

Da terminale il tasto backspace invece di cancellare il carattere immediatamente precedente stampa un ^H o qualcosa del genere:

stty erase <backspace>

Il mio script non viene eseguito

Per eseguire un file è necessario settari i corretti permessi di esecuzione:

chmod 755 file_da_eseguire.sh

Se comunque non viene eseguito potrebbe essere necessario settare correttamente la variabile PATH:

export PATH=.:$PATH

Usiamo la shell in maniera sicura

Evitare il segno “>” nel prompt: per molti può essere un problema

PS1="# "

PS2="# "

Lista i file “a colori”

Con questa funzione si definisce il nuovo comando lc che visualizza i file con colori diversi in base ai permessi

function lc() { 
	MYUSER=`id| tr -s '(' ' ' |tr -s ')' ' '| cut -d ' ' -f2` 
	MYGROUP=`id| tr -s '(' ' ' |tr -s ')' ' '| cut -d ' ' -f4` 
	ls -lrtb $* | \
	awk -v u=${MYUSER} -v g=${MYGROUP} '
	{
		printf "%-10s %3s %-8s %-8s %7s %3s %2s %5s ",
		$1,$2,$3,$4,$5,$6,$7,$8; 
		d=substr($1,1,1); 
		if ( $3==u ){ a=substr($1,2,3); } 
		else if ( $4==g ){ a=substr($1,5,3); } 
		else { a=substr($1,8,3); } 
		r=substr(a,1,1);w=substr(a,2,1);x=substr(a,3,1); 
		C=33; 
		if (d=="d"){ C=34; } 
		else if (x=="x"){ C=31; } 
		else if (w=="w"){ C=32; } 
		else if (r=="r"){ C=33; } 
		printf "%c[1;%sm",27,C; 
		for(i=9;i<=NF;i++){ 
		printf "%s ",$i; 
	} 
	printf "%c[0m\n",27; }' 
}

Confronto tra file

Diff massivo tra i file .c nella directory src e quelli nella $HOME

ls src/*.c | while read FILE  
do
   BFILE=`basename $FILE`
   diff $FILE $HOME/$BFILE > /dev/null
   if [ $? -ne 0 ]
   then
      echo $BFILE
      diff $FILE $HOME/$BFILE
   fi
done

Diff tra risultato di due comandi

diff <(printf "1\n2\n3\n") <(printf "1\n3\n")
2d1
< 2

Visualizza le righe in comune tra due file

Righe in comune tra una lista che inizia per r e una lista che inizia per ri:

/usr/xpg4/bin/grep -f inizio.r.txt inizio.ri.txt  
ricerca_external_id.sh
ripristino_k.sh
ripristinop.sh

Visualizza complemento tra due file

Dal file lista.txt elimina le righe presenti anche in lista1.txt:

cat lista.txt
pippo
pluto
paperino
topolino

cat lista1.txt
pluto
topolino

/usr/xpg4/bin/grep -v -f lista1.txt lista.txt
pippo
paperino

Compressione decompressione file

Gzip e tar in un colpo

tar cvf - file1 file2 file3 | gzip > file.tar.gz

Gzip diretto dell’output di un comando

L’output di un comando (in questo caso un ls) viene diretto in un file di pipe che riceve l’output del comando ed esegue il gzip, producendo un file gzippato senza la necessità di creare un file intermedio

mknod pipe_file p  
cat pipe_file | gzip > lista_file.gz &
ls -lrt > pipe_file
rm pipe_file

Cerca in un archivio .tar.gz il file contenente la stringa

TEXT="Stringa da cercare"
tar -ztf file.tar.gz | while read FILENAME 
do
   if tar -zxf test.tar.gz "$FILENAME" -O | grep "$TEXT" > /dev/null
   then
      echo "$FILENAME contiene $TEXT"
   fi
done