-
- 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
}
-
fun() {
for arg in "$@" ;do
while [ -n "$arg" ] ;do
printf "%c\n", "$arg"
arg="${arg#?}"
done
done
}
-
-
isnormal() {
tab=$(printf "\t")
case "$*" in
*[]["$tab"'|&;<>()$"?#~=%\ `*
'\']*) return 1 ;;
esac
}
-
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"
}
- 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
- 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
- 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
- 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).