#! /bin/sh wc "$@" | awk '{ printf "%.1f characters, %.1f words per line\n", $3/$1, $2/$1 }'Pelkästään awkillakin se sujuu, etenkin jos halutaan muuttaa sanan määritelmää, esim.
#! /bin/awk -f BEGIN { FS="[^-[:alpha:]]+" } { c += length()+1; w += NF - (!$1) - (!$NF) } END { printf "%.1f characters, %.1f words per line\n", c/NR, w/NR }
#! /bin/awk -f { for (i=1; i<=length(); ++i) { c=toupper(substr($0,i,1)) if (c ~ /[[:alpha:]]/ ) { n[c]++ total++ } } } END { for (c in n) printf "%c %.2f%%\n", c, n[c]/total*100 | "sort" }
#! /bin/sh FS=$1 ; shift awk -F"$FS" 'NF { t += NF-1 } END { print t }' "$@"
#! /bin/sh awk ' BEGIN { FS="[^-[:alpha:]]+" } { for (i=0; ++i<=NF;) if ($i) { n[$i]++; total++ } } END { for (i in n) printf "%s %d %.3f%%\n",i,n[i],n[i]/total*100 } ' | sort -k2,2n | tail
#! /bin/sh last "$@" | awk ' $1 !~ /^([a-z]|$)|reboot|date/ && $2 !~ "begins" { for (i=1; $++i !~ /Mon|Tue|Wed|Thu|Fri|Sat|Sun/ ;) ; date=$(i+2) " " $(i+3) if (olddate && date != olddate) { print olddate ":", total total=0 } olddate=date ++total } END { print olddate ":", total }'
#! /bin/sh last "$@" | awk ' $1 !~ /^[^a-z]|reboot|date/ && $2 != "begins" { for (i=1; $++i !~ /Mon|Tue|Wed|Thu|Fri|Sat|Sun/ ;) ; month=$(i+2) if (oldmonth && month != oldmonth) { print oldmonth ":",total total=0 } oldmonth=month total++ } END { print oldmonth ":" , total }'
#! /bin/sh last "$@" | awk ' /^$/ { exit } $1 !~ /^(reboot|date)$/ { t[$1]++ } END { for (u in t) print u,t[u] }'
#! /bin/sh # average number of different users logging in on each weekday # assuming there's at least one login per day last "$@" | awk ' !NF { exit } { for (i=1; $++i !~ /Mon|Tue|Wed|Thu|Fri|Sat|Sun/ && i<=NF;) ; date=$(i+1) $(i+2) if (date != olddate) { if (wday) { for (u in users) { delete users[u] ++daily[wday] } ++count[wday] } olddate=date wday=$i } } $1 !~ /^(reboot|date)$/ { users[$1]=1 } END { ++count[wday] for (d in daily) printf "%s: %d total in %d dates, %.2f average\n", d, daily[d], count[d], daily[d]/count[d] }'
Jos välipäivät (ilman yhtään loginia) halutaan laskea, tehtävä on olennaisesti vaikeampi. Seuraava versio toimii kunhan joka viikko on ainakin yksi login:
#! /bin/sh # average number of different users logging in on each weekday # assuming there's at least one login _every week_. last "$@" | awk ' BEGIN { prevday["Mon"]="Sun" prevday["Tue"]="Mon" prevday["Wed"]="Tue" prevday["Thu"]="Wed" prevday["Fri"]="Thu" prevday["Sat"]="Fri" prevday["Sun"]="Sat" } ! NF { exit } { for (i=1; $++i !~ /Mon|Tue|Wed|Thu|Fri|Sat|Sun/ ;) ; date=$(i+1) $(i+2) if (date != olddate) { if (wday) { for (u in users) { delete users[u] ++daily[wday] } ++count[wday] while ($i != prevday[wday]) { wday=prevday[wday] count[wday]++ } } olddate=date wday=$i } } $1 !~ /^(reboot|date)$/ { users[$1]=1 } END { ++count[wday] for (d in daily) printf "%s: %d total in %d dates, %.2f average\n", d,daily[d],count[d],daily[d]/count[d] }'Periaatteessa samalla logiikalla saisi käsitellyksi alle kuukauden tai alle vuodenkin loginittomat jaksot (yli 5 vuoden katkoja ei teoriassakaan enää voi aina hoitaa oikein).
#!/bin/sh sort -t: -k3n /etc/passwd | awk -F: -v limit=${1:-499} ' BEGIN { last=limit } { if ($3 <= limit) next if ($3 > last+1) { exit } last=$3 } END { print last+1 }'
tai
#!/bin/awk -f BEGIN { FS=":" limit=499 if (ARGV[1]) limit=ARGV[1] ARGC=1 last=limit while ("sort -t: -k3n /etc/passwd" | getline) { if ($3 <= limit) continue if ($3 > last+1) { exit } last=$3 } } END { print last+1 }
#! /bin/awk -f { for (i=0; ++i <= NF;) t[NR,i]=$i } END { for (i=0; ++i <= NF;) { for (j=0; ++j <= NR;) printf " %d",t[j,i] printf "\n" } }
#! /bin/awk -f $1 == "%DEFINE" { name=$2 sub("^" $1 "[ \t]*" $2 "[ \t]*","") values[name]=$0 next } { for (macro in values) gsub("%" macro "%",values[macro]) print }
#! /bin/awk -f BEGIN{ if (ARGV[1] !~ /^([0-9]+\.)?([0-9]+\.)?([0-9]+)(\.[0-9]+-[0-9]+)?$/) { printf "invalid argument" exit 1 } n=split(ARGV[1],a,"[.]") if (split(a[n],r,"-")<2) { r[1]=25; r[2]=255; ++n } if (n==2) { Cnet="130.234." a[1] } else if (n==3) { Cnet="130." a[1] "." a[2] } else { Cnet=a[1] "." a[2] "." a[3] } ARGV[1]="" if (!ARGV[2]) ARGV[1]="-" } /^;/{ next } /^[a-zA-Z]/{ hostname = $1 } /^[ \t]/{ $0 = hostname " " $0 } $2 == "IN" && $3 =="A" { used[$4]=1 } END{ for (c=r[1]; c<=r[2]; ++c) { ip=Cnet "." c if (!(ip in used)) print ip } }
tai
#! /bin/sh case $1 in [!0-9]*) Cnet=130.234.164; Range=25-128;; *.*.*.*) Cnet=${1%.*}; Range=${1##*.} ; shift ;; *.*.*) Cnet=$1; Range=25-128 ; shift;; *.*) Cnet=130.234.${1%.*}; Range=${1#*.} ; shift;; ?*) Cnet=130.234.$1; Range=25-128 ;shift ;; *) Cnet=130.234.164; Range=25-128 ;; esac Start=${Range%-*} Stop=${Range#*-} awk -v Cnet=$Cnet ' /^;/{ next } /^[a-zA-Z]/{ hostname = $1 } /^[ \t]/{ $0 = hostname " " $0 } $2 $3 == "INA" { print $4 }' "${@:-it.hosts}" >usedIPs awk 'BEGIN{ for (c='$Start'; c<='$Stop'; ++c) print "'$Cnet'." c }' | grep -vxf usedIPs
#! /bin/awk -f $1 == "KEY" { keys[$2]=$3 } keys[$1] { for (i=0; ++i<=keys[$1] ;) printf "%s ",$i printf "\n" }