Unix ja shell-ohjelmointi 2001, demo 2 Unix ja shell-ohjelmointi 2001, demo 2 mallivastaukset

    1. Vaihtoehtoja on paljon, esim.
      fun() {
        i=1
        while [ $# -gt 0 ] ;do
          printf "%d: '%s'\n" "$1"
          shift
          i=`expr $i + 1`     # tai i=$((i+1))
        done
      }
      

    2. fun() {
        for arg in "$@" ;do 
          while [ -n "$arg" ] ;do
             printf "%c\n", "$arg"
             arg="${arg#?}"
          done
        done
      }
      

    1. isnormal() {
        tab=$(printf "\t")
        case "$*" in
          *[]["$tab"'|&;<>()$"?#~=%\ `*
      '\']*) return 1 ;;
        esac
      }
      
    2. specials() {
        result=
        for char in '|' '&' ';' '<' '>' '(' ')' '$' '`' '\' '"' "'" \
      	'*' '?' '[' '#' '~' '=' '%' 
        do 
          case "$*" in *"$char"*)  result="$result$char" ;; esac
        done
        case "$*" in *" "*)  result="$result space" ;; esac
        case "$*" in *$(printf "\t")*)  result="$result tab" ;; esac
        case "$*" in *'
      '*)  result="$result newline" ;; esac
        [ ${#result} -ne 0 ] &&
              printf "special characters found:\n%s\n" "$result"
      }
      

  1. Huomaa että #!:n pitää olla tiedoston ensimmäisen rivin alussa, sen ja shellin polun välissä voi olla välilyönti, shellin polku on aina absoluuttinen (saattaa toimia ilmankin muttei pitäisi!), ja shellillä voi olla argumentteja tai optioita.
    #! /bin/sh
    for i in  "${1:-.}"/* "${1:-.}"/.* ;do
      [ -f "$i" ] || continue      # tutkitaan vain normaaleja tiedostoja
      read firstline <"$i"
      case "$firstline" in
        '#!'*) 
            shell=/${shell#*/}     # aina absoluuttinen polku
            shell=${shell%% *}     # parametreja voi olla
            printf "%s looks like a script that would be executed by %s\n" \
                "$i" "$shell"
            if [ -x "$i" ] 
            then printf "\tand it is executable, too\n"
            else printf "\tit is not executable though\n"
            fi
            if [ -x "$shell" ] 
            then printf "\tand %s exists and is executable, too\n" "$shell"
            else printf "\talthough there's no such shell\n"
            fi
         ;;
      esac
    done
    exit
    

  2. IFS tekee tämän helpoksi:
    #! /bin/sh
    OLDIFS="$IFS"
    s=0
    while read line
    do
      r=0
      IFS=","  
      for i in $line 
      do
         case "${i#[-+]}" in
    	  *[!0-9]*|'') printf "%s is not a number!" "$i" >&2 ;;
              *) r=$((r+i)) ;;
         esac  
      done
      IFS="$OLDIFS"
      printf "%d\n" $r
      s=$((s+r))
    done  
    printf "total=%d\n" $s
    exit
    

  3. Yksinkertaisimmillaan tämä käy näin (oletetaan että argumentteina annetaan $1=nimitiedosto ja $2=lempinimitiedosto ja tulos tulee stdoutiin):
    #! /bin/sh
    while read firstname lastname
    do
      read nickname <&3 
      printf '%s "%s" %s\n' "$firstname" "$nickname" "$lastname"
    done <"$1" 3<"$2"
    exit
    
    Tuo ei toimi jos etunimiä on useita. Sen voi hoitaa vaikkapa näin:
    #! /bin/sh
    while read name
    do
      firstnames="${name% *}"
      lastname="${name##* }"
      read nickname <&3
      printf '%s "%s" %s\n' "$firstnames" "$nickname" "$lastname"
    done <"$1" 3<"$2"
    exit
    

  4. Taas argumentteina $1=nimitiedosto ja $2=lempinimitiedosto, ja syöte stdinissä:
    #! /bin/sh
    >"$2"
    while read firstname nickname lastname
    do 
      printf "%s %s\n" "$firstname" "$lastname"
      nickname=${nickname#\"}
      nickname=${nickname%\"}
      printf "%s\n" nickname >>"$2"
    done >"$1" 
    exit
    
    Tuo ei taaskaan toimi jos etunimiä voi olla useita tai jos lempinimessä on välilyöntejä. Paremmin:
    #! /bin/sh
    while read line
    do 
      firstnames="${line%% \"*}"
      lastname="${line##*\" }"
      printf "%s %s\n" "$firstnames" "$lastname" 
      nickname="${nickname#\"}"
      nickname="${nickname%\"}"
      printf "%s\n" "$nickname" >&3
    done >"$1" 3>"$2"
    exit
    
    Toisenkin tiedoston uudelleensuuntaus while-silmukalle tiedostokahvalla 3 on nopeampaa kuin uudelleensuuntaus jokaiselle printfille erikseen kuten edellisessä (se avaa ja sulkee tiedoston joka kerta).


File translated from TEX by TTH, version 1.98.
On 31 Jan 2001, 18:18.