#!/bin/bash # array-ops.sh: 數組更多有趣的用法. array=( zero one two three four five ) # 元素 0 1 2 3 4 5 echo ${array[0]} # zero echo ${array:0} # zero # 第一個元素的參數擴展, #+ 從位置0開始 (即第一個字符). echo ${array:1} # ero # 第一個元素的參數擴展, #+ 從位置1開始 (即第二個字符). echo "--------------" echo ${#array[0]} # 4 # 數組第一個元素的長度. echo ${#array} # 4 # 數組第一個元素的長度. # (另外一種寫法) echo ${#array[1]} # 3 # 數組第二個元素的長度. # Bash的數組是0開始索引的. echo ${#array[*]} # 6 # 數組中元素的個數. echo ${#array[@]} # 6 # 數組中元素的個數. echo "--------------" array2=( [0]="first element" [1]="second element" [3]="fourth element" ) echo ${array2[0]} # 第一個元素 echo ${array2[1]} # 第二個元素 echo ${array2[2]} # # 由於初始化時沒有指定,所以值爲空(null). echo ${array2[3]} # 第四個元素 exit 0 #!/bin/bash # array-strops.sh: 用於數組的字符串操做符. # 由Michael Zick編碼. # 已徵得做者的贊成. # 通常來講,任何相似 ${name ... } 寫法的字符串操做符 #+ 都能在一個數組的全部字符串元素中使用 #+ 像${name[@] ... } 或 ${name[*] ...} 的寫法. arrayZ=( one two three four five five ) echo # 提取尾部的子串 echo ${arrayZ[@]:0} # one two three four five five # 全部的元素. echo ${arrayZ[@]:1} # two three four five five # 在第一個元素 element[0]後面的全部元素. echo ${arrayZ[@]:1:2} # two three # 只提取在元素 element[0]後面的兩個元素. echo "-----------------------" # 子串刪除 # 從字符串的前部刪除最短的匹配, #+ 匹配字串是一個正則表達式. echo ${arrayZ[@]#f*r} # one two three five five # 匹配表達式做用於數組全部元素. # 匹配了"four"並把它刪除. # 字符串前部最長的匹配 echo ${arrayZ[@]##t*e} # one two four five five # 匹配表達式做用於數組全部元素. # 匹配"three"並把它刪除. # 字符串尾部的最短匹配 echo ${arrayZ[@]%h*e} # one two t four five five # 匹配表達式做用於數組全部元素. # 匹配"hree"並把它刪除. # 字符串尾部的最長匹配 echo ${arrayZ[@]%%t*e} # one two four five five # 匹配表達式做用於數組全部元素. # 匹配"three"並把它刪除. echo "-----------------------" # 子串替換 # 第一個匹配的子串會被替換 echo ${arrayZ[@]/fiv/XYZ} # one two three four XYZe XYZe # 匹配表達式做用於數組全部元素. # 全部匹配的子串會被替換 echo ${arrayZ[@]//iv/YY} # one two three four fYYe fYYe # 匹配表達式做用於數組全部元素. # 刪除全部的匹配子串 # 沒有指定代替字串意味着刪除 echo ${arrayZ[@]//fi/} # one two three four ve ve # 匹配表達式做用於數組全部元素. # 替換最前部出現的字串 echo ${arrayZ[@]/#fi/XY} # one two three four XYve XYve # 匹配表達式做用於數組全部元素. # 替換最後部出現的字串 echo ${arrayZ[@]/%ve/ZZ} # one two three four fiZZ fiZZ # 匹配表達式做用於數組全部元素. echo ${arrayZ[@]/%o/XX} # one twXX three four five five # 爲何? echo "-----------------------" # 在從awk(或其餘的工具)取得數據以前 -- # 記得: # $( ... ) 是命令替換. # 函數以子進程運行. # 函數將輸出打印到標準輸出. # 用read來讀取函數的標準輸出. # name[@]的寫法指定了一個"for-each"的操做. newstr() { echo -n "!!!" } echo ${arrayZ[@]/%e/$(newstr)} # on!!! two thre!!! four fiv!!! fiv!!! # Q.E.D: 替換部分的動做其實是一個'賦值'. # 使用"For-Each"型的 echo ${arrayZ[@]//*/$(newstr optional_arguments)} # 如今Now, 若是if Bash只傳遞匹配$0的字符串給要調用的函數. . . # echo exit 0 #!/bin/bash # days-between.sh: Number of days between two dates. # Usage: ./days-between.sh [M]M/[D]D/YYYY [M]M/[D]D/YYYY # # Note: Script modified to account for changes in Bash 2.05b #+ that closed the loophole permitting large negative #+ integer return values. ARGS=2 # Two command line parameters expected. E_PARAM_ERR=65 # Param error. REFYR=1600 # Reference year. CENTURY=100 DIY=365 ADJ_DIY=367 # Adjusted for leap year + fraction. MIY=12 DIM=31 LEAPCYCLE=4 MAXRETVAL=255 # Largest permissable #+ positive return value from a function. diff= # Declare global variable for date difference. value= # Declare global variable for absolute value. day= # Declare globals for day, month, year. month= year= Param_Error () # Command line parameters wrong. { echo "Usage: `basename $0` [M]M/[D]D/YYYY [M]M/[D]D/YYYY" echo " (date must be after 1/3/1600)" exit $E_PARAM_ERR } Parse_Date () # Parse date from command line params. { month=${1%%/**} dm=${1%/**} # Day and month. day=${dm#*/} let "year = `basename $1`" # Not a filename, but works just the same. } check_date () # Checks for invalid date(s) passed. { [ "$day" -gt "$DIM" ] || [ "$month" -gt "$MIY" ] || [ "$year" -lt "$REFYR" ] && Param_Error # Exit script on bad value(s). # Uses "or-list / and-list". # # Exercise: Implement more rigorous date checking. } strip_leading_zero () # Better to strip possible leading zero(s) { #+ from day and/or month return ${1#0} #+ since otherwise Bash will interpret them } #+ as octal values (POSIX.2, sect 2.9.2.1). day_index () # Gauss' Formula: { # Days from Jan. 3, 1600 to date passed as param. day=$1 month=$2 year=$3 let "month = $month - 2" if [ "$month" -le 0 ] then let "month += 12" let "year -= 1" fi let "year -= $REFYR" let "indexyr = $year / $CENTURY" let "Days = $DIY*$year + $year/$LEAPCYCLE - $indexyr + $indexyr/$LEAPCYCLE + $ADJ_DIY*$month/$MIY + $day - $DIM" # For an in-depth explanation of this algorithm, see #+ http://home.t-online.de/home/berndt.schwerdtfeger/cal.htm echo $Days } calculate_difference () # Difference between to day indices. { let "diff = $1 - $2" # Global variable. } abs () # Absolute value { # Uses global "value" variable. if [ "$1" -lt 0 ] # If negative then #+ then let "value = 0 - $1" #+ change sign, else #+ else let "value = $1" #+ leave it alone. fi } if [ $# -ne "$ARGS" ] # Require two command line params. then Param_Error fi Parse_Date $1 check_date $day $month $year # See if valid date. strip_leading_zero $day # Remove any leading zeroes day=$? #+ on day and/or month. strip_leading_zero $month month=$? let "date1 = `day_index $day $month $year`" echo $date1 Parse_Date $2 check_date $day $month $year strip_leading_zero $day day=$? strip_leading_zero $month month=$? date2=$(day_index $day $month $year) # Command substitution. echo $date2 calculate_difference $date1 $date2 abs $diff # Make sure it's positive. diff=$value echo $diff exit 0 # Compare this script with #+ the implementation of Gauss' Formula in a C program at: #+ http://buschencrew.hypermart.net/software/datedif #!/bin/bash exec 3<007en exec 4<007cn no=1 while read f1 <&3 && read f2 <&4 do #echo $f1\($f2\) tmpname=${f1}"("${f2}")" #echo $tmpname allnames[$no]=$tmpname let "no+=1" done #let "count=no-1" no=1 for i in * do if ! [ -d $i ] then continue fi pref=${i:0:4} tmpname=${allnames[$no]} newname=$pref$tmpname #echo $newname if ! [ $i = $newname ];then mv -v $i $newname fi let "no+=1" done #!/bin/bash for i in * do if [ ! -d $i ];then continue fi cd $i \rm -v *gif *html *htm *js for j in * do if [ -d $j ] then \rm -rv $j continue fi #找出含有jpg或jpeg的圖片 a=`echo $j|grep jpg` xa=`echo $?` b=`echo $j|grep jpeg` xb=`echo $?` if [ $xa -eq 1 ] && [ $xb -eq 1 ] then \rm -v $j continue fi #獲得圖片的尺寸 sze=`identify $j|awk '{print $3}'` width=${sze%x*} height=${sze#*x} if [ $width -lt 400 ] && [ $height -lt 400 ] then \rm -v $j fi done cd .. done #!/bin/sh # Last modified: 2003年07月05日 星期六 00時09分44秒 [test] SOURCE=$1 TARGET=$2 #CP=./fack_cp CP=cp $CP "$SOURCE" "$TARGET" & CPID=$! isalive(){ out=`ps -p $1 2> /dev/null` return $? } while [ 1 ]; do { SSIZE=`/bin/ls -l $SOURCE | gawk "{print \\\$5}"` if [ -f $TARGET ]; then TSIZE=`/bin/ls -l $TARGET | gawk "{print \\\$5}"` else TSIZE="0" fi PERCENT=`echo "scale=2; $TSIZE/$SSIZE*100" | bc -l` RATE=`echo "scale=0; 63*$PERCENT/100" | bc -l` BLUE="\\033[3;44m" NORMAIL="\\033[0;39m" BAR=$BLUE i=0 while [ $i -le 62 ]; do [ $i = $RATE ] && BAR=$BAR"\\033[7;39m" BAR=$BAR" " let i=$i+1 done BAR=$BAR$NORMAIL echo -en "\r$BAR ${PERCENT}%" if ! isalive "$CPID"; then echo -en "\n"; exit; fi sleep 1 } done #!/bin/bash #eval命令的另外一種使用方法 #作算術運算要使用表達式((count=$#))或者let "count=$#", #若是使用count=$#賦值,shell則認爲count是字符串 ((count=$#)) cmd=echo while : do cmd="$cmd \$$count" ((count=`expr $count-1`)) if [ $count -eq 0 ] then break fi done eval $cmd #!/bin/bash let allrows=144/16 let allcols=176/16 #echo "allrows="$allrows #echo "allcols="$allcols #echo $# if [ $# -lt 1 ] then echo "Usage xxx row col" elif [ $# -eq 1 ] then let row=$1/$allrows let col=$1%$allcols echo "row="$row echo "col="$col elif [ $# -ge 2 ] then row=$1 col=$2 echo "row="$row echo "col="$col fi let rowS=$row*4+1 let rowE=$rowS+3 let colS1=$col*4+1 let colS2=$col*4+2 let colS3=$col*4+3 let colS4=$col*4+4 #echo "colS1="$colS1 "colS2="$colS2 "colS3"=$colS3 "colS4"=$colS4 #aa="${rowS},${rowE}" #echo $aa #sed -n "$rowS"','"$rowE"'p' mv.txt |awk '{print $colS1 $colS2 $colS3 $colS4}' sed -n "$rowS"','"$rowE"'p' mv.txt |awk -v colS1=$colS1 -v colS2=$colS2 -v colS3=$colS3 -v colS4=$colS4 '{print $colS1 $colS2 $colS3 $colS4}' #!/bin/bash # rnd.sh: 輸出一個10進制隨機數 # Script by Stephane Chazelas. head -c4 /dev/urandom | od -N4 -tu4 | sed -ne '1s/.* //p' # =================================================================== # # 分析 # ---- # head: # -c4 選項將取得前4個字節. # od: # -N4 選項將限制輸出爲4個字節. # -tu4 選項將使用無符號10進制格式來輸出. # sed: # -n 選項, 使用 "s" 命令與 "p" 標誌組合的方式, # 將會只輸出匹配的行. # 本腳本做者解釋 'sed' 命令的行爲以下. # head -c4 /dev/urandom | od -N4 -tu4 | sed -ne '1s/.* //p' # ----------------------------------> | # 假設一直處理到 "sed"命令時的輸出--> | # 爲 0000000 1198195154n # sed 命令開始讀取字串: 0000000 1198195154n. # 這裏它發現一個換行符, #+ 因此 sed 準備處理第一行 (0000000 1198195154). # sed命令開始匹配它的 <range> 和 <action>. 第一個匹配的而且只有這一個匹配的: # range action # 1 s/.* //p # 由於行號在range中, 因此 sed 開始執行 action: #+ 替換掉以空格結束的最長的字符串, 在這行中這個字符串是 # ("0000000 ") ,用空字符串(//)將這個匹配到的字串替換掉, 若是成功, 那就打印出結果 # ("p" 在這裏是 "s" 命令的標誌, 這與單獨的 "p" 命令是不一樣的). # sed 命令如今開始繼續讀取輸入. (注意在繼續以前, #+ continuing, 若是沒使用 -n 選項的話, sed 命令將再次 #+ 將這行打印一遍). # 如今, sed 命令讀取剩餘的字符串, 而且找到文件的結尾. # sed 命令開始處理第2行(這行也被標記爲 '$' # 由於這已是最後一行). # 因此這行沒被匹配到 <range> 中, 這樣sed命令就結束了. # 這個 sed 命令的簡短的解釋是: # "在第一行中刪除第一個空格左邊所有的字符, #+ 而後打印出來." # 一個更好的來達到這個目的的方法是: # sed -e 's/.* //;q' # 這裏, <range> 和 <action> 分別是 (也能夠寫成 # sed -e 's/.* //' -e q): # range action # nothing (matches line) s/.* // # nothing (matches line) q (quit) # 這裏, sed 命令只會讀取第一行的輸入. # 將會執行2個命令, 而且會在退出以前打印出(已經替換過的)這行(由於 "q" action), #+ 由於沒使用 "-n" 選項. # =================================================================== # # 也可使用以下一個更簡單的語句來代替: # head -c4 /dev/urandom| od -An -tu4 exit 0