function MihinPakettiinKäskyKuuluu { echo "koetanpa etsiä mihin pakettiin käsky:  $1  kuuluu: ";dpkg -S $1 | egrep -w $(which $1)$; }

function tehdä_uuden_kansion_tähän_kansioon () { 
echo 'Luon kansion nimeltä: '$kanta/"$KansionNimi"/"$UusiNimi"' ja sille arkistot' 
mkdir -p $kanta/"$KansionNimi"/"$UusiNimi"/ARKISTO/{SKRIPTIT,DOKUMENTIT,HISTORIAT,POISTETUT}
echo 1 > $kanta/"$KansionNimi"/"$UusiNimi"/ARKISTO/ViimeksiValittuSkriptiTässäKansiossa 
}

function kelpokokonaisluku () { [[ $(echo $1 | tr -d +-[0-9]) ]] && echo epäkelpo || echo kelvollinen ;}

function kelpoliukuluku () { [[ $(echo $1 | tr -d +-.e[0-9]) ]] && echo epäkelpo || echo kelvollinen ;}

function tekijät () { apu=$( factor $1 ); echo $apu | grep -Po '(?<=:).*' ;} # kutsuesimerkki: tekijät 256

function permutaatiot (){ eval echo $(printf "{%s,}" "$@"); }# kutsu: permutaatiot a b c d 

function matmax () { eval echo "\${$1[*]}" | tr ' ' '\n' | sort -nr | head -n1 ;}  # kutsu: matmax matrix # hyväksyy merkin ja desimaalin

function matmin () { eval echo "\${$1[*]}" | tr ' ' '\n' | sort -nr | tail -n1 ;}  # kutsu: matmin matrix # hyväksyy merkin ja desimaalin

function rowave() { count=$(echo $1 | wc -w); echo $(echo '('$1')/'$count | tr ' ' + | bc -l);}; # kutsu: rowave '1.2 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9'

function milloinviimeksijossainkansiossaontehtymuutoksia () { find /media/$USER/tikku/OMATSKRIPTIT -exec stat \{} --printf="%Y\n" \; | sort -n -r |  head -n 1 ;} # "%y\n" kunnon päiväys 

function tiedostolistaustekojärjestyksessä () { find ~/OMATSKRIPTIT -type f -print0 | xargs -r0 stat -c '%.19z %n' | grep -v /ARKISTO/ | grep -v .*~ | sort ;}

function lineave() { count=$(cat $1 | wc -w); echo $(echo '('$(cat $1 | tr '\n' + | head -c -1)')/'$count | bc -l);}; # kutsu: lineave tiedosto1
function lineave() { count=$(cat $1 | cut -d ' ' -f2 | wc -w); echo $(echo '('$(cat $1 | cut -d ' ' -f2 | tr '\n' + | head -c -1)')/'$count | bc -l);}; lineave tiedosto1 lineno
function sarakekeskiarvo() { count=$(cat $1 | cut -d ' ' -f$2 | wc -w); echo $(echo '('$(cat $1 | cut -d ' ' -f$2 | tr '\n' + | head -c -1)')/'$count | bc -l);}; sarakekeskiarvo tiedosto1 sarakkeen_numero  (kokeessa lineno=2)
function arvoa_vastaava_osoite_matriisissa () { echo; echo $1;apu=$( eval echo -e \${$1[@]} | sed 's/ /\n/g' | awk -v apu2=$2 '{if ($0==apu2) print NR" "}'); for n in $apu; do eval echo -e \${!$1[@]} | awk -v apu=$n '{print $apu}'; done ;} # kutsu: arvoa_vastaava_osoite_matriisissa matriisin_nimi arvo # toimii myös assosiatiivisen matriisin kanssa

function kertoma () { [[ $1 -eq 0 ]] && kertoma=1 || kertoma=$(seq -s* $1 | bc | tr -d '\\' | tr -d "\n" ) ;}; # kutsu: time kertoma 555; echo $kertoma 

function satunnaisnumero () { echo $(( RANDOM ));}

function satunnaisteksti () { date | md5sum | cut -c 1-32;} 

function OnkoSudoSalasanaVoimassa { sudo -n uptime 2>&1 | grep "load" | wc -l ; } # Tulos 1 jos se on voimassa ja 0 jos ei ole

function aikaboottauksesta () { echo $(uptime | awk '{print $3}' | tr -d ,);} # kutsu: ;echo -n 'aikaa viime bootista ';aikaboottauksesta 
                      
function ipv4testi () { echo $1 | awk -F. '$1<=255 && $1>=0 && $2<=255 && $2>=0 && $3<=255 && $3>=0 && $4>=0 && $4<=255' ;} # kutsu: ipv4testi 1.1.1.1
function ipv4testi () { echo $1 | grep -Po '[0-9]+.[0-9]+.[0-9]+.[0-9]+' | awk -F. '$1<=255 && $1>=0 && $2<=255 && $2>=0 && $3<=255 && $3>=0 && $4>=0 && $4<=255' ;} #kutsu: ipv4testi "tekstiä*iposoite*lisää teksiä*toinen ip*..." ip-osoitteet tulostuvat alekkaisille riveille...voi soveltaa tiedoston suodattamiseen ...   
function ipv4testi () { octet="(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])"; [[ $1 =~ ^$octet\.$octet\.$octet\.$octet$ ]]; }     # regex-toteutus, "ei nopein"
function ipv4testi () { for n in {0..255}; do echo $1 | grep -w 0*$n; done | [[ $(wc -l) = 4 ]] ;}                          # hidas
function ipv4testi () { echo $1 | egrep '^(([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$'
                                        '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'

function ipv6testi () { [[ $(echo $1|tr -d :[[:xdigit:]]) = '' && $(echo $1|tr -dc :|wc -c)<7 && $(echo $1|grep -o '[[:xdigit:]]*'|wc -L)<5 ]] && echo osoite on kelvollinen;}; # kutsuesimerkki: ipv6testi ::1

function ajoita () { (time $@) 2>&1 | grep real | tr ms  ' ' | awk '{print 60*$2+$3}';}  # kutsuesimerkki: ajoita sleep 1.234  tai: ajoita . tiedosto

function tyhjää_näppäinbufferi () { read -t 0.001 -N 10000 ;} # kutsu: tyhjää_näppäinbufferi 

function matriisin_pisin_jäsen () { echo $(($(eval echo -e "' '\${$1[@]/%/\\\n}" | wc -L)-1));} # kutsuesimerkki: matriisin_pisin_jäsen natriisin_nimi

# kun tiedostossa on vain yksi sarake ja rivejä tuntematon määrä
function keskipoikkeama () { awk '{sum+=$1; sumsq+=$1*$1} END {printf "%f", sqrt(sumsq/NR - (sum/NR)^2)}' /tmp/lukemat ;}  
function keskiarvo () { awk '{sum+=$1} END {printf "%f", sum/NR}' /tmp/lukemat ;} 
function maksimi () { awk 'BEGIN {maksimi=-9e99} { if ($1>maksimi) maksimi=$1 } END { print maksimi }' /tmp/lukemat ;} 
function minimi () { awk 'BEGIN {minimi=9e99} { if ($1<minimi) minimi=$1 } END { print minimi }' /tmp/lukemat ;}
function korvaa_yksi_maksimi_ja_minimi_keskiarvolla () { keskiarvo=$(keskiarvo); maksimi=$(maksimi); minimi=$(minimi)
  echo 'maksimi:'$maksimi'   minimi:'$minimi'  kumpikin korvataan keskiarvolla:'$keskiarvo; sed -i "s/$maksimi/$keskiarvo/g" /tmp/lukemat; sed -i "s/$minimi/$keskiarvo/g" /tmp/lukemat ;}

# kun tiedostossa on tuntematon määrä sarakkeita ja rivejä:
function keskipoikkeama () { # uusiksi
sarake=1; [[ $1 ]] && sarake=$1
kohde=taulukko; [[ $2 ]] && kohde=$2
case $sarake in
    1 ) awk '{sum+=$1; sumsq+=$1*$1} END {print sqrt(sumsq/NR - (sum/NR)^2)}'  "/home/$(whoami)/"$kohde  ;; # ensimmäisen sarakkeen normaalipoikkeama 
    2 ) awk '{sum+=$2; sumsq+=$2*$2} END {print sqrt(sumsq/NR - (sum/NR)^2)}'  "/home/$(whoami)/"$kohde  ;; # toisen sarakkeen normaalipoikkeama 
    3 ) awk '{sum+=$3; sumsq+=$3*$3} END {print sqrt(sumsq/NR - (sum/NR)^2)}'  "/home/$(whoami)/"$kohde  ;; # kolmannen sarakkeen normaalipoikkeama
    4 ) awk '{sum+=$4; sumsq+=$4*$4} END {print sqrt(sumsq/NR - (sum/NR)^2)}'  "/home/$(whoami)/"$kohde  ;; # neljännen sarakkeen normaalipoikkeama
    5 ) awk '{sum+=$5; sumsq+=$5*$5} END {print sqrt(sumsq/NR - (sum/NR)^2)}'  "/home/$(whoami)/"$kohde  ;; # viidennen sarakkeen normaalipoikkeama
esac ;}


function muisti () { muistia=$(free | grep Mem: | awk '{print $2}')
vapaana=$(free | grep Mem: | awk '{print $4}')
prosentti=$(echo "scale=2 ;100*("$muistia"-"$vapaana")"/$muistia | bc);}

function ajat () { echo -n 'viimeksi muutettu: '; stat -c %y $1 | awk '{print $2" "$1}'; echo -n 'viimeksi käytetty: '; stat -c %x $1 | awk '{print $2" "$1}';}

function TarkistaOnkoSkriptissäKontrollimerkkejä () { # valikkonäppäimille
cp $kanta/"$KansionNimi"/"$ValitunTeksti" /tmp/delme
for i in {01..19} 0b 0c 0d 0e 0f 1a 1b 1c 1d 1f; do apu='\x'$i; sed -i "s/${apu}//g" /tmp/delme; done #; cat -v delme
echo $(diff $kanta/"$KansionNimi"/"$ValitunTeksti" /tmp/delme); [[ $(diff $kanta/"$KansionNimi"/"$ValitunTeksti" /tmp/delme) ]] && { 
Valittavat=("Ei tehdä mitään" "Stripataan kontrollimerkit pois. Alkuperäinen kopioidaan ARKISTO/POISTETUT kansioon")
ValitseValittavistaYksi "Mitäpä tehdään:"
[[ $ValitunTeksti = "Stripataan kontrollimerkit pois. Alkuperäinen kopioidaan ARKISTO/POISTETUT kansioon" ]] && {
  cp $kanta/"$KansionNimi"/"$ValitunTeksti" $kanta/"$KansionNimi"/ARKISTO/POISTETUT/"$ValitunTeksti"
  for i in {01..19} 0b 0c 0d 0e 0f 1a 1b 1c 1d 1f; do apu='\x'$i; sed -i "s/${apu}//g" $kanta/"$KansionNimi"/"$ValitunTeksti"; done 
}
}
} 

function MerkkijonostaMatriisiksi () { 
# Kun välieroitin ei ole välilyönti niin se täytyy laittaa kutsun kolmanneksi parametriksi. Kun välieroitin on jotakin muuta kuin välilyönti niin merkkijonossa saa olla välilyöntejä.
matriisinnimi=$1
unset matriisinnimi
[[ $3 ]] && IFS=$3
set -- $(echo "$2"); for (( n=1; n<=$#; n++ )); do eval $matriisinnimi[$n]='$(eval echo \${$n})' ; done
unset IFS
} 

function tulosta_vikakappale () { vika=$(cat "$1" | grep -Pn ^$  | cut -d: -f1 | tail -1);awk "NR>$vika" "$1" ;} # kappaleiden välissä pitää olla tyhjä rivi. Tiedoston viimeinen rivi voi myös olla tyhjä rivi 

function tulosta_matriisi () {
eval echo -e \${$1[@]} 
}
 
function tulosta_matriisi2 () {
function Tulosta_matriisin_rivi () { 
eval echo -e \${$1[@]} 
}
[[ $3 ]] && echo $3 || echo 'matriisin: '$1' tuloste:'
Sarakeluku=$2
Rivi=0
while true; do
  for (( n=0; n<=Sarakeluku-1; n++ )); do  
    [[ ! $(eval echo -e \${$1[n+$Sarakeluku*Rivi]}) ]] && Tulosta_matriisin_rivi xxxx && return
    xxxx=$xxxx" "$(eval echo -e \${$1[n+$Sarakeluku*Rivi]}) 
  done
  Tulosta_matriisin_rivi xxxxsana
  xxxx=''
  let Rivi++
done
}

function plot_matrix () { eval echo \${$1[*]} | tr ' ' '\n' | gnuplot -p -e 'plot "/dev/stdin" with lines' ;}

function tulosta_parametri () { # kutsu esim: tulosta_parametri 11111 {99999..1}  # tulosta 11111:s jäsen joukosta: 99999 99998 ... 3 2 1
monennestako_parametrista_alkaen=$1
montako_tulostetaan=1
#echo ${@:(-$monennestako_parametrista_alkaen):$montako_tulostetaan}  # perästäpäin laskettuna
echo ${@:$monennestako_parametrista_alkaen+1:$montako_tulostetaan}    # alustapäin laskettuna
}

function tulosta_matriisi3 () {
echo -n 'Matriisin jäsenten arvot     (tulosteessa on välilyönti jäsenten välissä): '; eval echo -e \${$1[*]\n}
echo -n 'Matriisin jäsenten osoitteet (tulosteessa on välilyönti jäsenten välissä): '; eval echo \${!$1[*]}
}
 
function rivisummat () {
awk '{for(i=1;i<=NF;i++) t+=$i; print "rivisumma:",t; t=0}' $1  # taulukon rivisummien laskeminen kun taulukon kokoa ei tiedä
} esim: cat ~/matriisi | awk 'BEGIN {j=0} {for(i=1;i<=NF;i++) t+=$i; print "rivin",j" summa: ",t; t=0 j++}'

function sarakesummat () {
# enimmäisessä looppissa lasketaan sarakesummat matriisiin ja toisessa loopissa ne tulostetaan. Vertaa rivisummat
# $1 on täydellinen tiedostonimi. -F ":" on sarakejakomerkki jonka voi jättää pois kun se on välilyönti.
awk -F ":"  '{for(i=1;i<=NF;i++) s[i]+=$i} END {for(i=1;i<=NF;i++) print "sarakesumma=" s[i]}' $1 # taulukon sarakesummien laskeminen kun taulukon kokoa ei tiedä
} esim: cat ~/matriisi | awk  'BEGIN {j=0}{for(i=1;i<=NF;i++) s[i]+=$i} END {for(i=1;i<=NF;i++) print "sarakeen",j," summa=" s[i]}'
# cat ~matriisi| awk'{ORS=(NR%5?FS:RS)}1'

function vastinalkiosumma () {
# samanmuotoisten matriisien vastinjäsenien yhteenlasku ja tulostus:
# tiedostoja voi lisätä tai poistaa käskystä muuttamatta missään mitään. Tiedostojen rivi- ja sarakeluku otetaan myös automaattisesti huomioon 
  awk 'FNR==1{cnt=1}
  NF>nf{nf=NF}
  {for(i=1;i<=nf;i++)s[cnt++]+=$i}
  END {for(i=1;i<cnt;i++)printf i%nf?"%d ":"%d\n",s[i]}' $1 $2 # ~/tiedosto1 ~/tiedosto2 ~/tiedosto3
}
 
function käänteismatriisi () { 
awk '{ for (i=1; i<=NF; i++)  {
        a[NR,i] = $i
    }}
NF>p { p = NF }
END {    
    for(j=1; j<=p; j++) {
        apu=a[1,j]
        for(i=2; i<=NR; i++){
            apu=apu" "a[i,j];
        }
        print apu }}' $1
}

function vastinalkiosumma () {
# samanmuotoisten matriisien vastinjäsenien yhteenlasku ja tulostus:
# tiedostoja voi lisätä tai poistaa käskystä muuttamatta missään mitään. Tiedostojen rivi- ja sarakeluku otetaan myös automaattisesti huomioon 
  awk 'FNR==1{cnt=1}
  NF>nf{nf=NF}
  {for(i=1;i<=nf;i++)s[cnt++]+=$i}
  END {for(i=1;i<cnt;i++)printf i%nf?"%d ":"%d\n",s[i]}' $1 $2 # ~/tiedosto1 ~/tiedosto2 ~/tiedosto3
}

function kuvata_tiedosto_graafisesti () {
  gnuplot <<_EOF_
    set term postscript enhanced color
    set output "$kanta/testResults.dat.eps"
    set title 'testResults'
    p "$kanta/testResults.dat" u 1:2 w l
_EOF_
evince $kanta/testResults.dat.eps
}


function tehdä_uuden_kansion_tähän_kansioon () { 
echo 'Luon kansion nimeltä: '$kanta/"$KansionNimi"/"$UusiNimi"' ja sille arkistot' 
mkdir -p $kanta/"$KansionNimi"/"$UusiNimi"/ARKISTO/{SKRIPTIT,DOKUMENTIT,HISTORIAT,POISTETUT}
echo 1 > $kanta/"$KansionNimi"/"$UusiNimi"/ARKISTO/ViimeksiValittuSkriptiTässäKansiossa 
}

function etsi_samannimiset_skriptit () { # tai pikemminkin: nimiltään samantapaiset
ValitunTekstiTalteen=$ValitunTeksti
avaimet="end=palaa Skriptiajuriin jatkamaan skriptintekoa           home=peru skriptinteko"
hakusana="$1"
ValitunNumero=1
eval Valittavat=(" "$(find $kanta/OMATSKRIPTIT |  grep  "$hakusana" | grep -v /ARKISTO/ | grep -v *sgml | sed 's/^ */"/g;s/ *$/"/g'))
while true
do  
  [[ ! ${Valittavat[0]} ]] && break
  ValitseValittavistaYksi "näillä skripteillä on samankaltainen nimi: katso enteriä painamalla onko joku samanlainen kuin se minkä aiot tehdä" "$avaimet" 
  [[ $Tapahtuma = "end" ]] && ValitunTeksti=$ValitunTekstiTalteen && break
  [[ $Tapahtuma = "home" ]] && ValitunTeksti=$ValitunTekstiTalteen && SkriptinNimi="" && return 
  gedit "$ValitunTeksti"
  let ValitunNumero++
done 
}

function etsiä_skriptistä_kontrollimerkit () { # TARVITAANKO
echo "Kontrollimerkit ovat joskus tarpeellisia eivätkä tarpeettomatkaan aina aikaansaa vikoja, mutta joskus ne invalidisoivat ja lisäksi niin ettei se näy ja usein ei huomaa etsiä."
echo "Ensiksi etsitään kontrollimerkit tyyppiä \n, nämä ovat yleensä tarpeellisia:"
[[ -f $kanta/"$KansionNimi"/"$ValitunTeksti" ]] && cat $kanta/"$KansionNimi"/"$ValitunTeksti" | tr -dc '[:cntrl:]' | od -c && echo && echo
echo 'Ja sitten kontrollimerkit tyypiltään:  M- ja: C- (Nämä ovat yleensä merkki "kontrollimerkeistä" ja usein tarpeettomia. Huomioi että ääkköset on poistettu)'; echo
cp $kanta/"$KansionNimi"/"$ValitunTeksti" /tmp/delme1
cat /tmp/delme1 | tr -d äöÄÖ > /tmp/delme2
cat -v /tmp/delme2 | grep -e M- -e C- 
read -p 'konrollimerkit saat poistettua geditissä: poista kontrollimerkkien jälkeinen ja edellinen merkki ja kirjoita ne heti takaisin. paina enter jatkaakseesi'
}

function orpojen_poisto () {
echo 'orpo-tiedostojen poisto'
for n in  $kanta/"$KansionNimi"/ARKISTO/SKRIPTIT/*; do [[ ! -f $(echo "$n" | sed 's/ARKISTO\/SKRIPTIT//g') ]] && echo 'poistan:' "$n" && rm -rf "$n"; done 
for n in  $kanta/"$KansionNimi"/ARKISTO/DOKUMENTIT/*; do [[ ! -f $(echo "$n" | sed 's/ARKISTO\/DOKUMENTIT//g') ]] && echo 'poistan:' "$n"&& rm -rf "$n"; done
for n in  $kanta/"$KansionNimi"/ARKISTO/HISTORIAT/*; do [[ ! -f $(echo "$n" | sed 's/ARKISTO\/HISTORIAT//g') ]] && echo 'poistan:' "$n"&& rm -rf "$n"; done
echo 
}

# matriisin diagonaalin tulostaminen:
awk '{++f; print $f}' infile > outfile

function numeromerkiksi () { printf \\$(printf %o $1); };  # kirjoittaa merkin kun ascii-koodi annetaan
function merkkinumeroksi () { printf %d \"$1;}             # kirjoittaa ascii-koodin kun merkki annetaan 

function  käskynlähde() ( set -o pipefail; [[ $(type $1 | grep sisäänrakennettu ) ]] && echo sisäänrakennettu || which $1 | xargs -r readlink -f | xargs -r dpkg -S ; (( $? )) && echo käskyä ei ole ;); käskynlähde käskyn_nimi
function  käskynlähde() ( set -o pipefail; [[ $(type $1  2> /dev/null | grep sisäänrakennettu ) ]] && echo sisäänrakennettu || which "$@" | xargs -r readlink -f | xargs -r dpkg -S ;  (( $? )) && echo -n käskyä ei ole asennettu mutta se löytyy paketista: && apt-cache search $1 | awk '{print $1}' | grep -w ^$1 ;); käskynlähde xargs

function g() { return; }; function löytyyköfunktio () { declare -f $1 > /dev/null; (( ! $? )) && echo funktio löytyy || echo funktiota ei löydy ;}; löytyyköfunktio g



