Przykłady skryptów

    -- Sebastian Pawlak


Przykłady skryptów

Przykładowe skrypty w BASHu. Najlepiej jest się uczyć analizując przykłady.

#!/bin/bash
# Program odczytuje ze standardowego wejscia liczbe i sprawdza czy istnieje
# odpowiedni argument skryptu.

echo "Który argument (liczony od 1) ? "
read i

if [ $i -le $# -a $i -gt 0 ]; then  # jesli i <= LICZBA_ARGUMENTOW i i > 0
  echo -n "Argument nr $i istnieje i wynosi: "
  shift `expr $i - 1`
  echo $1
else
  echo "Argument nr $i nie istnieje"
fi





#!/bin/bash
#
# Skrypt kopiuje pliki z przyrostkiem ~ do katalogu BACKUP

if [ -e "./BACKUP" -a  ! -d "./BACKUP" ]; then  # jezeli istnieje plik BACKUP
                                                # i nie jest katalogiem
  echo "BACKUP juz istnieje i nie jest katalogiem"
  exit
fi

if [ ! -d "./BACKUP" ]; then   # jezli nie istnieje katalog BACKUP
  mkdir "./BACKUP"
fi

for i in *~; do
  echo "Kopiuję plik $i do katalogu BACKUP"
  cp "$i" "./BACKUP"
done







#!/bin/bash
# Skrypt znajduje wszystkie pliki, ktore maja w swojej tresci swoja nazwe

for i in *; do
  if [ -f "$i" ]; then     # jezli to jest plik
    z=`cat $i | grep $i`   # wypisanie pliku i poszukiwanie w jego tresci nazwy
    if [ -n "$z" ]; then   # jezeli plik zawiera w swojej tresci swoja nazwe
      echo "Plik $i zawiera w swojej treści swoja nazwę"
    fi
  fi
done






#!/bin/bash
# Skrypt wczytuje liczby i wypisuje max., min. i sumę

if [ $# -lt 1 ]; then           # jeżeli nie podano argumentów
  echo "Podaj nazwe pliku!"
  exit
fi

if [ ! -f "$1" ]; then          # jeżeli podany jako argument plik nie istnieje
  echo "Plik $1 nie istnieje!"
  exit
fi

rozmiar=`cat "$1" | wc -l`      # liczba wierszy w pliku
if [ $rozmiar -eq 0 ]; then     # jeżeli liczba wierszy w pliku wynosi 0
  echo "Plik $1 jest pusty!"
  exit
fi

min=`cat "$1" | head -n 1`     # na poczatku max i min równają się pierwszej
max=$min                       #   liczbie w pliku
suma=0                         # na początku suma wynosi 0

while [ $rozmiar -gt 0 ]; do   # przeczytaj cały plik
  liczba=`cat "$1" | tail -n $rozmiar | head -n 1`  # pojedynczy wiersz pliku

  if [ $liczba -gt $max ]; then    # jeżeli liczba > niż dotychczasowy max
    max=$liczba                    #   max staje się liczbą
  elif [ $liczba -lt $min ]; then  # jeżeli liczba < niż dotychczasowy min
    min=$liczba                    #   min staje się liczbą
  fi

  suma=$[ $suma + $liczba]         # zwiększamy sumę o kolejną liczbę

  rozmiar=$[ $rozmiar - 1 ]        # rozmiar pliku zmniejszamy o 1
done

echo "Max. liczba $max"
echo "Min. liczba $min"
echo "Suma liczb $suma"









#!/bin/bash
# Procedura zamieniająca liczbę na jej reprezentację słowną

procedura()
{
  if [ $1 -lt 0 -a $1 -gt 99 ]; then
    echo "Liczba w nieprawidłowym zakresie!"
    exit
  fi

  case $1 in
    10) echo "dziesięć" ;;
    11) echo "jedenaście" ;;
    12) echo "dwanaście" ;;
    13) echo "trzynaście" ;;
    14) echo "czternaście" ;;
    15) echo "piętnaście" ;;
    16) echo "szesnaście" ;;
    17) echo "siedemnaście" ;;
    18) echo "osiemnaście" ;;
    19) echo "dziewiętnaście" ;;
    2?) echo -n "dwadzieścia " ;;   # -n -- nie przechodź do następnego wiersza
    3?) echo -n "trzydzieści " ;;
    4?) echo -n "czterdzieści " ;;
    5?) echo -n "pięćdziesiąt " ;;
    6?) echo -n "sześćdziesiąt " ;;
    7?) echo -n "siedemdziesiąt " ;;
    8?) echo -n "osiemdziesiąt " ;;
    9?) echo -n "dziewięćdziesiąt " ;;
  esac

  if [ $i -lt 10 -o $i -gt 19 ]; then  # jeżeli liczba < 10 i liczba > 19
    case $1 in
       0) echo "zero" ;;
      ?0) echo "" ;;
      *1) echo "jeden" ;;
      *2) echo "dwa" ;;
      *3) echo "trzy" ;;
      *4) echo "cztery" ;;
      *5) echo "pięć" ;;
      *6) echo "sześć" ;;
      *7) echo "siedem" ;;
      *8) echo "osiem" ;;
      *9) echo "dziewięć" ;;
    esac
  fi
}


# test procedury
i=0
while [ $i -le 99 ]; do
  procedura $i

  i=$[ $i + 1 ];
done








#!/bin/bash
# Skrypt wyznacza n-tą liczbę Fibbonacciego
# Program wyznacza liczbę metodą iteracyjną

echo "Podaj numer liczby Fibbonacciego: "
read i

if [ $i -lt 1 ]; then
  echo "Wymagany numer większy od zera!"
  exit
fi

# 1 1 2 3 5 8 13 21

if [ $i -le 2 ]; then      # dwie pierwsze liczby Fibbonacciego to jedynki
  echo "1";
  exit
fi

i=$[ $i - 2 ]
a=1
b=1

while [ $i -gt 0 ]; do     # wykonuje pętlę jeżeli i > 0
  c=$[ $a + $b ]
  a=$b
  b=$c

  i=$[ $i - 1 ]
done

echo $c









#!/bin/bash
# ./skr1 plik1 [ plik2 [ plikn ] ]
# Program wypisuje naprzemiennie kolejne linie plikow podanych jako parametry.

if [ $# -lt 1 ]; then
    echo 'brak parametru(ow) !'
    echo './skr1 plik1 [ plik2 [ plikn ] ]'
    exit
fi

lineNumber=1
pusty=0    # liczba plikow, ktore zostaly wyswietlone w calosci

while [ $pusty -ne $# ]; do

    pusty=0
    color=31
    for i in $*; do
        color=$[ color + 1 ]
        if [ $lineNumber -gt `wc -l "$i" | awk '{print $1}'` ]; then 
            pusty=$[ $pusty + 1 ]
        else
            echo -e "\\033[0;${color}m"`cat "$i" | head -n $lineNumber\
	    | tail -n 1`"\\033[0;37m"   # wyswietla linie
        fi
    done
    lineNumber=$[ $lineNumber + 1 ]     # kolejna linia pliku

done








#!/bin/bash
# ./skr2
# Program przeszukuje drzewo katalogow i 
# usuwa pliki *.jpg mniejsze niz 5000bajtow - calkiem przydatny.

rozmiar=0
for i in `find -type f -printf "%s:%p\n" | grep .jpg$`; do
    rozmiar=${i%:*}
    if [ $rozmiar -lt 5000 ]; then
     rm "${i#*:}"
    fi
done







#!/bin/bash
# ./skr3 katalog1 [ katalog2 [ katalog3 ] ]
# Program przeszukuje zadane katalogi i wyswietla informacje o tych
# wszystkich plikach wewnatrz tych katalogow, ktore maja w swojej
# tresci swoja nazwe.

if [ $# -eq 0 ]; then
    echo 'brak parametru(ow) !'
    echo './skr3 katalog1 [ katalog2 [ katalog3 ] ]'
    exit
fi

while [ $# -gt 0 -a -d "$1" ]; do
   licznik=0
   for i in `find $1 -type f -printf "%p " 2>/dev/null`; do 
      # a tu bedzie sztuczka znana z C ...
      [ "`grep -l ${i##*/} $i 2>/dev/null`" ] && licznik=$[ $licznik + 1 ]
   done   

   echo katalog $1 ma $licznik plikow, ktore maja w swojej tresci swoja nazwe
   shift
done







#!/bin/bash
# ./skr4 katalog
# Program przeszukuje zadany katalog i wyswietla informacje
# o najwiekszym i najmniejszym pliku.

if [ $# -lt 1 -o $# -gt 1 ]; then
    echo 'bledny parametr !'
    echo './skr4 katalog'
    exit
fi

katalog=$1

max=0         # taki sposob dzialania (poprzez nadanie malej i ogromnej
min=99999999  # wartosci) nie jest zadowalajacy z punktu widzenia algorytmiki
              # ale spelnia wymogi praktyczne
for i in `find $katalog -type f -printf '%s:%p\n' | sort -n -t ' '`; do
    w=${i%%:*}
    if [ $w -gt $max ]; then
        max=$w
        maxn="$i"
    fi
    if [ $w -lt $min ]; then
        min=$w
        minn="$i"
    fi
    echo "$i"
done

echo 'najwiekszy:' "$maxn"
echo 'najmniejszy:' "$minn"







#!/bin/bash
# ./skr5 katalog plik
# Program przeszukuje podany katalog w celu odnalezienia wszystkich
# plikow 'plik' - wynik poszukiwan posortowany jest wedlug rozmiaru.

find "$1" -type f -name "$2" -printf "%f %s\n" | sort -n -t' ' -k 2 







#!/bin/bash
# ./skr6 katalogZrodlowy katalogDocelowy
# Program przeszukuje katalogZrodlowy i do kazdego pliku lub
# katalogu tworzy w katalogDocelowym link o nazwie plikX (gdzie
# X to kolejny numer) lub o nazwie katalogX dla katalogu.
# UWAGA: nalezy podac sciezki bezwzgledne

if [ $# -ne 2 ]; then
    echo 'bledne parametry !'
    echo './skr6 katalogZrodlowy katalogDocelowy'
    exit
fi
 
Nplk=0
Nktl=0

if [ ! -d "$2" ]; then
    mkdir "$2"
fi

for i in `find "$1"`; do

    if [ -f "$i" ]; then     # plik
        ln -s "$i" "$2/plik$Nplk"
        Nplk=$[ $Nplk + 1 ]
    elif [ -d "$i" ]; then   # katalog
        ln -s "$i" "$2/katalog$Nktl"
        Nktl=$[ $Nktl + 1 ]
    fi

done







#!/bin/bash
# ./skr7 [-r] katalog
# Program wyszukuje w zadanym katalogu linki, ktore na nic nie wskazuja.
# Jezeli podano parametr `-r' to nastepuje proba usuniecia tych linkow.

if [ $# -lt 1 -o $# -gt 2 ]; then
    echo 'zla liczba parametrow !'
    echo './skr7 [-r] katalog'
    exit
fi

if [ "$1" = '-r' ]; then
    katalog="$2"
else
    katalog="$1"
fi

echo 'linki, ktore na nic nie wskazuja:'
for i in `find "$katalog" -type l`; do
    if [ ! -f `readlink "$i"` -a ! -d `readlink "$i"` ]; then
        echo -n "$i  ->  `readlink "$i"`"
        if [ "$1" = '-r' ]; then
            rm -f "$i" 2>/dev/null
            if [ -L "$i" ]; then
                echo -n '  nie udalo sie skasowac'
            else
                echo -n '  udalo sie skasowac'
            fi 
        fi 
        echo
    fi
done







#!/bin/bash
# ./skr8 katalog
# Program dla kazdego podkatalogu zadanego katalogu wyswietla
# sumaryczna wielkosc znajdujacych sie tam plikow.

if [ $# -ne 1 ]; then
    echo 'zla liczba parametrow !'
    echo './skr8 katalog'
    exit
fi

for i in `find "$1" -type d`; do
   tmp=0
   for j in `find "$i" -type f -printf "%s "`; do
       tmp=$[ $tmp + $j ]  
   done 
   echo "$i  $tmp"
done







#!/bin/bash
# ./skr9 plik rozmiar
# Program dzieli plik na czesci po `rozmiar' wierszy.

if [ $# -ne 2 ]; then
    echo 'bledna liczba parametrow !'
    exit
fi

rozmiar=`wc -l "$1"`
rozmiar=${rozmiar% *}

Nplk=0
while [ $[ $2 * $Nplk ] -lt $rozmiar ]; do

    cat "$1" | tail -n $[ $rozmiar - $2 * $Nplk ] | head -n $2 
    echo '-------'

    Nplk=$[ $Nplk + 1 ]

done






Zaliczeniowy skrypt eksternistyczny, SOP 1999/2000

Napisac skrypt flat, który spłaszcza strukturę katalogów w następujący
sposób i korzysta z następujących założeń:

* skrypt przyjmuje jedną opcję -l, po której następuje liczba oznaczająca
  ile poziomów w drzewie katalogów należy spłaszczyć. Liczba 0 oznacza brak
  spłaszczania, 1 bieżemy pod uwagę tylko podkatalogi, 2 podkatalogi i ich podkatalogi
  itd.. Brak opcji -l oznacza spłaszczanie całej struktury.

* jeżeli skrypt dostanie (oprocz opcji -l) dwa parametry, to pierwszy parametr
  oznacza korzeń drzewa katalogów do spłaszczenia, a drugi katalog w jakim umieszczamy
  wynik. Jeżeli skrypt dostanie jeden parametr, to jest nim katalog wynikowy, a
  splaszczamy wszystko poczawszy od katalogu bieżącego. Odpowiednie przykłady wywołań:

  flat -l 10 katalog_spłaszczany tu_umieść_wynik
  flat tu_umieść_wynik
  
  W pierwszym przypadku spłaszczamy do 10 poziomów (jeżeli jest ich mniej to oczywiście
  wszystkie) drzewa o korzeniu katalog_spłaszczany i wynik umieszczamy w nowo zakładanym
  katalogu tu_umieść_wynik. W drugim przypadku spłaszczamy maksymalnie bieżący katalog,
  a wynik umieszczamy w tu_umieść_wynik. Możemy przyjąć, że wynik nie może być umieszczany
  wewnątrz katalog_splaszczany.

* spłaszczenie wygląda następująco - dla każdego podkatalogu w drzewie katalog_spłaszczany,
  obojętnie na którym poziomie, w katalogu tu_umieść_wynik powstaje jeden katalog o
  takiej samej nazwie.
  (*) Jeżeli nazwy podkatalogów powtarzają się to należy poprzedzić je jednoznacznym
  prefiksem (np. ścieżka do niego). W każdym z tych nowo utworzonych katalogów zakładamy
  linki (dowiązania) symboliczne wskazujące na katalogi, które teraz są już w katalogu
  tu_umieść_wynik, a które pierwotnie były podkatalogami. Nazwy tych linków są takie jak
  nazwy podkatalogów w pierwotnym drzewie (patrz (*) - czyli w przypadku powtórzeń linki
  o starych nazwach wskazują na katalogi o nowych nazwach (z prefiksami)).
* pliki pozostają w tych podkatalogach, w których były do tej pory.

Przykład. Mamy drzewo:

            a
           / \
          /   \
         b     c
        /     /|\
       /     / | \
      d     e  f  d

Po wykonaniu spłaszczenia mamy: W katalogu tu_umieść_wynik znajduje się 7 podkatalogów
o nazwach a, b, c, d, e, f, c_d (ta ostatnia nazwa to przykład). Podkatalog a zawiera
wszystkie pliki z a (w drzewie pierwotnym) oraz linki: o nazwie b, wskazujący na b oraz
o nazwie c wskazujący na c. Podkatalog b zawiera wszystkie pliki z b oraz linki o nazwie
d, wskazujący na katalog d. Podkatalog c zawiera wszystkie pliki z c oraz linki e, f i d
wskazujące odpowiednio na e, f i c_d. Podkatalogi e, f i c_d zawierają wszystkie pliki,
które zawierały do tej pory e, f oraz d będące podkatalogami c.


#!/bin/bash

########################################
#         Zaliczeniowy skrypt          #
#           eksternistyczny            #
#            SOP 1999/2000             #
########################################
#           Sebastian Pawlak           #
#     nr albumu: s1222, grupa: 311     #
########################################

### zmienne globalne
#####################

katalogSplaszczany=`pwd`      # aktualny katalog
tuUmiescWynik=`pwd`
maxGlebokoscSplaszczania=-1   # (-1) -> splaszcza cala strukture
wynikPlus=''

### generowanie jednoznacznego prefiksu
### funkcja konwertuje napis zawierajacy sciezke (ze slash`ami) na napis
### zawierajacy te sciezke ale zamiast slash`ow beda znaki "_"
#########################################################################

function konwertuj() {
    local s="$1"
    local d="$1"'x'
    local wynik=$wynikPlus
    
    while [ "$s" != "$d" ]; do
        d="${s%%/*}"   # pierwszy wyraz (od poczatku do slash`a)
        s="${s#*/}"    # wszystko oprocz pierwszego wyrazu
        wynik="$wynik$d"
        if [ "$s" != "$d" ]; then
	    wynik=$wynik'_'
	fi
    done
        
    echo "$wynik"
}


### glowna funkcja skryptu ; rekurencyjnie przeglada podkatalogi, tworzy ich
### kopie w katalogu "tuUmiescWynik" (uwzglednia powtarzajace sie nazwy),
### kopiuje pliki, tworzy linki
#############################################################################

function splaszcz() {
    local katalog="$1"          # katalog
    local aktualnaGlebokosc=$2  # glebokosc w drzewie rekurencyjnym
    local docelowy

    docelowy="$tuUmiescWynik/`konwertuj "$katalog"`"  # kat. docelowy z prefiksem
    mkdir "$docelowy" 2>/dev/null    # tworzy katalog w "tuUmiescWynik"

    echo "$katalog --> $docelowy"
    cp `find $katalog -type f -maxdepth 1` $docelowy 2>/dev/null # kopiow. plikow

    # "kopiowanie" linkow z odswiezaniem ich wskazan
    for i in `find $katalog -type l -maxdepth 1 -printf "%p\n"`; do
	linkdest=`find $katalog -name "${i##*/}" -type l -maxdepth 1 -printf "%l"`

        tmpKatalogBazowy=`pwd`
	cd "$katalog" # katalog z linkiem
	if [ -z "${linkdest%/*}" ]; then               # katalog lub plik w korzeniu
	    rzeczywisteWskazanie="/${linkdest##*/}"
	elif [ "${linkdest%/*}" != "$linkdest" ]; then # wskazanie na katalog
	    tmpKatalog=`pwd`
	    cd "${linkdest%/*}"
	    rzeczywisteWskazanie="`pwd`/${linkdest##*/}"
	    cd "$tmpKatalog"
	else                                           # wskazanie na plik
	    rzeczywisteWskazanie="`pwd`/${linkdest##*/}"
	fi
	cd "$tmpKatalogBazowy"

        tmpContain=`echo "$rzeczywisteWskazanie" | grep ^"$katalogSplaszczany"`
	if [ -n "$tmpContain" ]; then  # link wskazuje na element w drzewie
	    ln -s "../`konwertuj "$rzeczywisteWskazanie"`" "$docelowy/${i##*/}"
	else # link wskazuje poza drzewo splaszczane
	    ln -s "$rzeczywisteWskazanie" "$docelowy/${i##*/}"
	fi	
    done 
    
    
    for k in `find $katalog -type d -mindepth 1 -maxdepth 1`; do
        if [ $maxGlebokoscSplaszczania -eq -1 \
                 -o $aktualnaGlebokosc -lt $maxGlebokoscSplaszczania ]; then
            splaszcz "$k" $[ $aktualnaGlebokosc + 1 ]  # rekurencyjne wywolanie
            ln -s "$celLinka" "$docelowy" 2>/dev/null  # tworzenie linka
        fi
    done
  
    celLinka="$docelowy"  # nazwa aktualnego katalogu jest linkiem dla katalogu
                          # polozonego plycej w zaglebieniu rekurencyjnym
}



#######################################
### sterowanie przebiegiem programu ###
#######################################

echo 'flat, s1222'

### identyfikacja parametrow przekazanych do skryptu
###################################################

while [ $# -ne 0 ]; do
    if [ `expr "$1" = '-l'` -eq 1 ]; then
        shift
        maxGlebokoscSplaszczania=$1
    else
        katalogSplaszczany=$tuUmiescWynik
        tuUmiescWynik="$1"
    fi
    shift
done

echo -n 'glebokosc splaszczania: '
if [ $maxGlebokoscSplaszczania -eq -1 ]; then
    echo 'cala struktura'
else
    echo $maxGlebokoscSplaszczania
fi

if [ ! -d "$katalogSplaszczany" ]; then
    echo "katalog splaszczany nie istnieje"
    exit
fi

if [ -d "$tuUmiescWynik" ]; then
    echo "katalog docelowy juz istnieje"
    exit
fi

mkdir "$tuUmiescWynik" 2>/dev/null  # tworzy "tuUmiescWynik" (jesli nie istnial)

aktualnyKat=`pwd`
cd "$katalogSplaszczany"
katalogSplaszczany=`pwd`
cd "$aktualnyKat"
cd "$tuUmiescWynik"
tuUmiescWynik=`pwd`
cd "$aktualnyKat"

tmpKt=`echo "$katalogSplaszczany" | grep '/'`
if [ -z "$tmpKt" ]; then
    wynikPlus='_'
fi

echo '   katalog splaszczany:' $katalogSplaszczanyRoot
echo '      katalog wynikowy:' $tuUmiescWynik

if [ $maxGlebokoscSplaszczania -eq 0 ]; then
    echo "brak splaszczania"
    exit
fi

if [ "$katalogSplaszczany" = "$tuUmiescWynik" ]; then
    echo "katalog wynikowy i katalog splaszczany to ten sam katalog !"
    exit
fi

### wywolanie glownej funkcji, ktora dokona splaszczenia struktury podkatalogow
###############################################################################

splaszcz "$katalogSplaszczany" 0   # glowna funkcja

echo 'koniec.'
w3cw3c
automatyka przemysłowa