Week 07

When you do coding:
  • Avoid the I/O bottle neck.
  • Explicitly assign the temporary filename.

    Review: group \( \) and repetition \{ \} in sed

    echo "1234567890" | sed -e ':a' -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta'
    echo "1234567890" | sed -e ':a' -e 's/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/;ta'

    or shorter,
    echo "1234567890" | sed -re ':a;s/(.*[0-9])([0-9]{3})/\1,\2/;ta'

    Compare with its reverse operation,
    echo "1234567890" | sed -re ':a;s/([0-9]{3})([0-9].*)/\1,\2/;ta'

    ○If we have a sample HTML file that outputs like this:

    Assign the content of "Lin Dong Tsai Hsieh Yu" to an array of five elements, then print the print array contents. Array index in bash starts with 0.
    LASTNAME="Lin Dong Tsai Hsieh Yu"  string input
    arr=($LASTNAME)                    assign string to the array named arr
    echo ${arr[0]} ${arr[3]}           print the values of arr[0] and arr[3]
    echo ${arr[*]}                     print all the values in array arr
    echo ${!arr[*]}                    print the indices of array arr
    echo ${#arr[*]}                    print the lengths of array arr
    echo ${#arr[@]}                    also print the lengths of array arr
    b=`seq 1 9`                        b is a string
    brr=(`seq 1 9`)                    brr is an array
    arr=(`echo "Lin Dong Tsai Hsieh Yu"`)assign array via stdout
    

    Try to define a new tag, for example, <EXPL> and set its font style/color/weight in the CSS header. Change the text colored in red into your new style-tag of <EXPL> in the sample HTML file using one single sed command.

    Review: Numeric array in bash

    Periodic table of elements of Z=1—10.
    INDEX    1 2 3 4 5 6 7 8 9 10
    VALUE   H He Li Be B C N O F Ne
    declare -a atom
    atom="H He Li Be B C N O F Ne"
    echo ${#atom[@]}
    1
     
    echo ${atom[@]} ; echo ${!atom[@]} H He Li Be B C N O F Ne 0 ↑↑↑The whole string is treated as one single value stored in atom[0] unset -v atom Delete the whole array of atom[@]
    atom=(`echo "H He Li Be B C N O F Ne"`) or atom=($(echo "H He Li Be B C N O F Ne")) echo ${#atom[@]} 10
    echo ${atom[@]} ; echo ${!atom[@]} H He Li Be B C N O F Ne 0 1 2 3 4 5 6 7 8 9 ↑↑↑Now atom[@] has 10 elements, but the array starts with index 0
    echo ${atom[2]} Li This is stupid because we want to have He for Z=2. unset -v atom atom=(`echo "X H He Li Be B C N O F Ne"`) or atom=($(echo "X H He Li Be B C N O F Ne")) echo ${#atom[@]} 11
    for (( i=0 ; i <= ${#atom[@]} ; i+=1 )) ; do echo -n "Z=$i is ${atom[$i]}; " ; done Z=0 is X; Z=1 is H; Z=2 is He; Z=3 is Li; Z=4 is Be; Z=5 is B; Z=6 is C; Z=7 is N; Z=8 is O; Z=9 is F; Z=10 is Ne; unset atom[0] ↑↑↑Only delete the zeroth element atom[0]; the syntax of unset $atom[0] is incorrect
    echo ${atom[@]} ; echo ${!atom[@]} H He Li Be B C N O F Ne 1 2 3 4 5 6 7 8 9 10 echo ${atom[0]} ↑↑↑Prints an empty line because the zeroth element atom[0] has been deleted.
    echo ${#atom[@]} 10 ↑↑↑The array now has 10 elements. atom+=($(echo "Na")) ↑↑↑Append data into existing array echo ${atom[@]} ; echo ${!atom[@]} H He Li Be B C N O F Ne Na 1 2 3 4 5 6 7 8 9 10 11 The array now has 11 elements.

    Associative array in bash

    Associative array is only supported in bash version 4.2+
    echo $BASH_VERSION
    bash --version
    which bash

    ↓↓↓Table of animal sounds. Reference source: Ylvis, What does the fox say? (2013).
    KEY dog cat bird mouse cow frog elephant duck fish seal fox
    VALUE   woof meow tweet squeek moo croak toot squack blub owowow What
    declare -A sound
    associative array must be declared with -A before it can be used.
    
    sound[dog]=woof
    sound[cat]=meow
    sound[bird]=tweet
    sound[mouse]=squeek
    ......
    fill the array one by one, or
    
    declare -A sound=( [dog]=woof [cat]=meow [bird]=tweet [mouse]=squeek )
    fill the array at once.
    
    echo ${sound[dog]}
    woof
    echo ${sound[mouse]}
    squeek
    echo ${#sound[bird]}
    5
    animal=mouse
    echo ${sound[$animal]}
    squeek
    echo ${!sound[@]}
    mouse cat dog bird
    echo ${sound[@]}
    squeek meow woof tweet
    echo ${#sound[@]}
    4
    sound+=( [cow]=moo [frog]=croak )
    echo ${#sound[@]}
    6
    for KEY in "${!sound[@]}" ; do echo $KEY goes ${sound[$KEY]} ; done 
    mouse goes squeek
    cat goes meow
    dog goes woof
    cow goes moo
    bird goes tweet
    frog goes croak
    
    (Or you can also try
    for KEY in "${!sound[@]}" ; do echo -e "\e[33m$KEY \e[97mgoes \e[36m${sound[$KEY]}\e[0m" ; done
    to see the result.) reference
    
    unset -v sound[frog]
    echo ${sound[frog]}
    
    ↑↑↑Prints a blank line since the value has been deleted.
    
    KEYS=(${!sound[@]}) ; for (( i=0; i<"${#sound[@]}" ; i++ )) ; do \
    key=${KEYS[$i]} ; echo $key says ${sound[$key]} ; done
    mouse says squeek
    cat says meow
    dog says woof
    cow says moo
    bird says tweet
    ↑↑↑sound[@] is an associative array, while KEYS[@] is a numeric array.
    
    unset -v sound
    echo ${#sound[@]}
    0
    ↑↑↑The whole array was deleted. sound[@] must be declared again before it can be used as an associative array.
    
    
    Table of Atoms

    Exercise 1: Write a script to fill the associative array from the above table at once.
    Exercise 2: Write a script to calcuate the molecular weight from the input chemical formula.

    unset -v a ; a=(`sed -e 's/[ \t]\{1,\}/ /g' ~jsyu/animal.txt |head -1`)
    unset -v b ; b=(`sed -e 's/[ \t]\{1,\}/ /g' ~jsyu/animal.txt |tail -1`)
    unset -v sound ; declare -A sound ; for ((i=0 ; i<${#a[@]} ; i++)) ; do sound+=( ["${a[$i]}"]="${b[$i]}" ) ; done 











    Ref: http://www.artificialworlds.net/blog/2012/10/17/bash-associative-array-examples