Bash

From mmmv_kos
Jump to: navigation, search

Programmeerimiskeeled



Awk/gawk

Teooria

$1  tähistab üksiku rea 1. tulpa
$2  tähistab üksiku rea 2. tulpa
$3  tähistab üksiku rea 3. tulpa

Üldskeem:
    echo "babla" | gawk '{mingi tegevus}'

    echo "uhUu" | gawk '{print toupper($1)}'
    echo "uhUu" | gawk '{print tolower($1)}'


Koodinäited

echo " |x|" | awk '{ gsub(/\|/, "\\&"); print }'


# The following line will work only on a single line input, id est the "\nC" will not be processed.
printf "a\\t b\nC" | gawk '{ gsub(/ |\t/, "X"); print }' 
printf "a\\t b\nC" | gawk '{ gsub(/\s/, "X"); print }'   # equivalent to the previous line
                                                         # which prints a linebreak at the end.


printf "a\\t b\nC" | gawk '{gsub(/\s/,"X");printf "%s", $1 }' # without a linebreak

echo "aa bb" | gawk '{printf "%s",$0 }' # prints all columns

echo "aaa" | gawk '{i=length;printf "%s", i }' # prints string length

# Kustutuab kõik mitte-numbrid, tühikud kaasa arvatud:
printf "_a 42-\tY\nG" | gawk '{gsub(/\s+/,""); printf "%s", $1}' | gawk '{gsub(/[^012345678]+/,""); printf "%s", $1 }'


S8na "gold" sisaldavate ridade selekteerimine failist conins.txt ja iga rea 5.,6.,7.8. s8na kuvamine:

awk '/gold/ {print $5,$6,$7,$8}' coins.txt


Failide ja kataloogide nimed eraldi ridadel:

ls -l | awk '{ gsub(/[-rwxd]{10}[ \t]+[0-9][\t ]+[^\t ]+[\t ]+[^\t ]+[\t ]+[^\t ]+[\t ]+[^\t ]+[\t ]+[0-9]+[\t ]+[0-9:]+[\t ]+/, ""); print }'

Sõne pööramine (arhiivkoopia):

# Rubys oleks see: "ihaa".reverse
printf "ihaa" | awk '{ for(i=length;i!=0;i--)x=x substr($0,i,1);}END{printf  x}'


grep

# Konsoolile trykitakse rida, kus asub XXX ning 5 sellele reale j2rgnevat rida.
cat ./jura.txt | grep -A 5 XXX

# Kuvab leiu asukoha reanumbri.
grep -n XXX ./tigula_skript.bash | gawk '{print $1}' | gawk '{gsub(":","");print}'

wc

Sõna wc ei tähista siin kemmergut, vaid tuleneb väljendist word count.

# Ridade loendamine.
wc -l ./tigula_skript.bash | gawk {'print $1'}

date

year_month_day_T_hour_minute_second

S_TIMESTAMP="`date +%Y`_`date +%m`_`date +%d`_T_`date +%H`h_`date +%M`min_`date +%S`s"


echo

Reavahetusevaba "echo":

printf "Tere!"


Reavahetuse salvestamine sõnesse

    #----------------
    # The newline trick 
    local S_NEWLINE=$'\n'
    # originates from the answer of Gordon Davisson:
    # https://stackoverflow.com/questions/17821277/how-to-separate-multiple-commands-passed-to-eval-in-bash
    # archival copy: https://archive.fo/7XI3a 
    #----------------

Sõna-sõnalised eritähenduslikud märgid ("escaping")

printf "%q" "AA BB CC $^ \ / '\`\" <>()[];.{}" | xargs ruby -e "puts(ARGV[0])"


Reavahetused (Line Breaks, Linebreaks)

    echo $'UFO\nvaatleb'
    echo "------------------------"
    S_0="tere\np2evast"
    S_0+="\nveel\nkord" # lisab suffiksi
    ruby -e "puts 'Ruby väljund on:'; puts \"$S_0\""
    echo "------------------------"
    echo "printf väljnud on:"
    printf "%b" $S_0
    echo "[ja printf ei pane ise lõppu reavahetust]"
    echo "------------------------"


Järjekordne näide internetiavarustest:

IFS='' read -r -d '' String <<"EOF"
<?xml version="1.0" encoding='UTF-8'?>
 <painting>
   <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
   <caption>This is Raphael's "Foligno" Madonna, painted in
   <date>1511</date>-<date>1512</date>.</caption>
 </painting>
EOF


S_1=""
S_1+="`echo 'rida 1'`\n"
S_1+="`echo \"rida 2\"`\n"
S_1+="`echo \"rida 3\"`\n"
S_1+="`java -version`\n"

printf "%b" "$S_1"
echo "[printf väljundi lõpp]"

# Annab väljundiks ligikaudu:
#-----------------------------------
#openjdk version "1.8.0_181"
#OpenJDK Runtime Environment (IcedTea 3.9.0) (openSUSE project build 1.8.0_181-b13)
#OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
#rida 1
#rida 2
#rida 3
#
#[printf väljundi lõpp]
#-----------------------------------
# sõltumata sellest, et "java -version" oli
# kõige viimane sõne-genereerimis-rida, mitte esimene.

Värviline tekst ja tekstistiilid

... on kirjeldatud Fabien LOISON'i kodulehel, mille arhiivkoopiast leidub ka at softf1.com arhiivkoopia.

exit

The exit error code is of type C/C++ unsigned byte.

exit 0   # Exits without errors.
exit 1   # Exits with an error.
exit     # The default is to exit with an error.

# 1B unsigned byte integer overflow demo:
exit 255 # Exits with a custom  error  code of 255.
exit 256 # Exits with a custom "error" code of 0, id est exits without any errors.
exit 259 # Exits with a custom  error  code of 3.
exit -6  # Exits with a custom  error  code of 250.

echo $?  # Displays the error status of the previously
         # executed command.


Ctrl-Z

S_PROCESS_ID="<something>"
kill -s 19 $S_PROCESS_ID  # Ctrl-Z, pauses the process
kill -s 18 $S_PROCESS_ID  # "continue", wakes the process up again

File:2016 10 05 toggle process sleep mode t1.rb


find

K8ik jar-failid, mis muutusid viimase 72 minuti jooksul, kataloogis ./ ja rekursiivselt ./ alamkataloogides:

    find . -name '*.jar' -mmin -72

K8ik java-failid mis muutusid viimase 90 p2eva jooksul, mille "ls -l" v2ljund sisaldab s8ne "2008-03-05", kataloogis ./ ja rekursiivselt ./ alamkataloogides:

    find . -name '*.java' -mtime -90 | xargs ls -l | grep 2008-03-05


Search/Replace

Replace only the first occurrence in an environment variable

A="AOxAOxAOx"
A=${A/AO/z}
echo "$A" # == "zxAOxAOx"

Replace all occurrences in an environment variable:

A="AOxAOxAOx"
A=${A//AO/z}
echo "$A" # == "zxzxzx"


Multiline Comments

XXX=$(cat<< 'txt1' #=======================================================

Tyhikud 'txt1' ymber on kohustuslikud.

K8ik sulud () ja jutum2rgid ('',"") peavad siin piirkonnas
olema '' PAARIS ja jutum2rkide paaride paarilised peavad
m8lemad asuma samal real, sest syntaksi v2rvimine Vim-is ei pruugi
muidu toimida. V8tmefraasiks, mida guugeldada, on: Bash HERE document
Testida tasub mitme eri Linuxi distro peal, sest kohati leidub
versioonierinevusi.

J2rgmise rea l8pus ei tohi olla isegi tyhikut.
txt1
)#-------------------------  kommentaari l8pp  ----------------------------


Üks võimalik lahendus aadressilt unix.stackexchange.com:

: << 'A_BASH_HEREDOCHACK_TAG'
This is an abuse of the null command ':' and 
the here-document syntaxto achieve a "multi-line comment".
A_BASH_HEREDOCHACK_TAG


Continuation Lines

echo "continuation \
lines"

produces

continuation lines


Otse-käivitatavad skriptid

#!skripti_jooksutava_interpretaatori_absoluutfailirada

or

#!/usr/bin/env PATH_kaudu_käivitatava_interpretaatori_nimi


Nüansid

Tulenevalt Linux'i kerneli koodis olevast konstandi väärtusest on skripti_jooksutava_interpretaatori_absoluutfailirada maksimaalseks pikkuseks 127 tähemärki.

Loops

For

#!/usr/bin/env bash 
#==========================================================
S_FP_ARG="~/"
#---------------------
S_FP_0="`pwd`"
cd $S_FP_ARG

for s_iter in $( ls ); do
if [ -d "$s_iter" ]; then
     echo "A folder: $s_iter" 
else
     echo "A file or a link: $s_iter" 
fi
done

cd $S_FP_0
#---------------------

For over an Array

#!/usr/bin/env bash 
#==========================================================
AR_0=("aa" "bb" "cc")
echo ""
S_TMP=${#AR_0[@]}
echo "AR_0 length: $S_TMP"
echo ""
for s_iter in ${AR_0[@]}; do
     echo "AR_0 element: $s_iter" 
done
echo ""
S_TMP=${AR_0[0]}
echo "The first element of the AR_0 is: $S_TMP"
echo ""
#-------------------
#--------
#  The "ls -m" works with both, Linux and BSD.
AR_1=$( ls -m ~/ )
#--------
S_TMP=${#AR_1[@]}
echo "AR_1 length: $S_TMP"
echo ""
# A Bash loop related hack that uses Bash internal variable, 
# the "Internal Field Separator"
IFS=","
AR_2=()
for s_iter in ${AR_1[@]}; do
     AR_2+=($s_iter)
done
unset IFS
#-------
S_TMP=${#AR_2[@]}
echo "AR_2 length: $S_TMP"
echo ""
for s_iter in ${AR_2[@]}; do
     echo "AR_2 element:[$s_iter]" 
done


Incluce/Require/Require_once/etc

source $TSENTRAALKODU/m_local/etc/s8lmest_s8ltumatu_bashrc.bash


Repeditive Inclusion

a.bash:

#!/usr/bin/env bash
if [ "$S_AAA" != "" ]; then
    echo "exists: $S_AAA"
else
    echo "missing"
fi

b.bash:

#!/usr/bin/env bash
S_FP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
S_FN_SCRIPTFILE="`basename ${BASH_SOURCE[0]}`"
    
export S_AAA="horse"
source $S_FP_DIR/a.bash

export S_AAA="cat"
source $S_FP_DIR/a.bash

export S_AAA=""
source $S_FP_DIR/a.bash

Console output of the b.bash:

exists: horse
exists: cat
missing


A Script for Finding the Absolute path of a bash Script

    S_FP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"


Related:

    S_FN_SCRIPTFILE="`basename ${BASH_SOURCE[0]}`"


if-else

If-lauses on -e, -h, -d, -h, -f korral failirada või sõne kajastava muutuja ümber olevad jutumärgid kohustuslikud, sest vastupidisel juhul kood tühikut sisaldava failirajaga ei toimi.

if [ "$RAUDROHI_HOME" == "" ]; then
        echo ""
        echo "The environment variable RAUDROHI_HOME is not set, but "
        echo "it must be set or this script will not run (properly)."
        echo ""
        echo "The RAUDROHI_HOME must point to the folder that contains "
        echo "the folders src, IDE, doc, attic ."
        echo ""
        exit;
fi
cd $RAUDROHI_HOME;

S_WRONG_RAUDROHI_HOME_VALUE="false"
#------
if [ -e ./src ]; then
if [ ! -d ./src ]; then
    S_WRONG_RAUDROHI_HOME_VALUE="true"
fi
else
    S_WRONG_RAUDROHI_HOME_VALUE="true"
fi


S_TMP_0="`ls /home/pi/.nix-* 2>/dev/null`" # checks, if files exist
if [ "$S_TMP_0" != "" ]; then
    S_TMP_1="/tmp/jura"
    mkdir -p $S_TMP_1
    mv -f /home/pi/.nix-* $S_TMP_1/
fi


read -p "Use Foo? (Yes/whatever_else) " S_TMP_0
S_TMP_1="`echo $S_TMP_0 | gawk '{print tolower($1)}'`"
if [ "$S_TMP_1" == "yes" ]; then
    echo " We use Foo"
else
    echo " We do not use Foo"
fi


Comparison of Numbers

SI_LEN_0="-31"
SI_LEN_1="-30"

echo "The numbers: SI_LEN_0=$SI_LEN_0  SI_LEN_1=$SI_LEN_1"

if [ "$SI_LEN_0" -lt "$SI_LEN_1" ]; then  # "A -lt B" equiv "A < B"
    echo "SI_LEN_0 < SI_LEN_1 "
else
    echo "SI_LEN_0 => SI_LEN_1 "
fi


Symbolic Links

#S_FP="/home/ts2/tmp/kiire_xx1"
#S_FP="/home/ts2/tmp/jama.txt"
#S_FP="/home/ts2/tmp/xx6"
#S_FP="/home/ts2/tmp/broken_symbolic_link"
S_FP="/home/ts2/tmp/olematu_fail"

if [ -h "$S_FP" ]; then
    echo "symbolic link, regardless of whether it is broken or not"
    if [ ! -e "$S_FP" ]; then
        echo "the symbolic link is broken"
    else
        echo "the symbolic link is NOT broken"
    fi
else
    if [ -d "$S_FP" ]; then
        echo "folder"
    else
        if [ ! -d "$S_FP" ]; then
            echo "file, regardless of whether it exists of not"
        else
            echo "If this text is displayed,"
            echo "then this bash script has a flaw."
        fi
    fi
fi


String Length Equals zero

#!/usr/bin/env bash

S_TMP_0=""
if [ -z "$S_TMP_0" ];then
   echo "String length is zero."
else
   echo "String length is NOT zero."
fi


Is file or a link to a file

#!/usr/bin/env bash
#---------------------
S_FP_0="`pwd`"
for s_iter in $( ls ); do
if [ -f "$s_iter" ]; then
     echo "     A file or a link 2 a file: $s_iter" 
else
     echo "A folder or a link to a folder: $s_iter" 
fi
done
cd $S_FP_0
#---------------------

Functions

fun_tere () {
    local S_LOCAL_VARIABLE="Hi"
    printf "%s" "$S_FP $S_LOCAL_VARIABLE"
} # fun_tere

S_FP="tervitus"
fun_tere  # Nii kutsutakse asja v2lja
echo "$S_LOCAL_VARIABLE will not be said"


Functional Programming

func_hi() {
    echo "Hi!"
} # hi

func_bye() {
    echo "Bye!"
} # func_bye

AA="func_hi"
eval ${AA}
AA="func_bye"
eval ${AA}


Kopeerimiseks-asetamiseks mõeldud kood

Bash : Kopeerimiseks-asetamiseks mõeldud kood


IO

read -p "Siin on kysimus? " VASTUSE_MUUTUJA

echo "Ja vastus on: $VASTUSE_MUUTUJA"


Compression pipe

echo "ihii" | gzip - > a_nice_compressed_file.gz


Lõimedega seonduv

Võtmefraas: "join" (Ruby "join" analoog Bashis.)

espeak 'Hello, clouds of this world!' 2>/dev/null &  # läheb taustatööks
echo "ihaa1"  # Ilmub ekraanile kohe
wait $!       # "$!" peaks andma viimase protsessi ID ehk "Process ID"/PID
echo "ihaa2"  # Ilmub ekraanile alles pärast heli lõppu.

References