Script Examples

Some Simple Shell Script Examples

為一堆檔案更改檔名

Filtering and Conversion

Cut a block of lines from a file

GrepDom - Basic

GrepDom - 可任意指定比對的欄位

GrepDom - 可任意指定比對的欄位及輸出欄位

FTP

Math: Compute Average, Maximum and Minimum

Spelling Tools

Scripts for HTML

Code Generator 1

Code Generator 2

FAQ


Untitled Document
Some Simple Shell Script Examples
 
WARNING:
Exception handling are all omitted in the following examples.
Use these scripts with caution!!
以下所舉之範例均省略掉必要的意外處理,使用者在使用時應注意到這個問題, 尤其是在更動檔案時,避免對檔案造成意外的更動。
 
這裡的 shell script 分為兩種,一種是直接在 command line 下的, 所有參數都是直接給定的, 另一種則是存成檔案做成可以重複使用的指令, 所需的參數在script 中用變數代表(例如 $1, $2, $*等變數), 由使用者在叫用該 script 時才給定的。 在「用法」 裡有說明Script的叫用方式,但有些 script 沒有標明「用法」, 讀者可以從 script 中輕易的看出如何使用,自行製作成指令。

 

功能 grep pattern from several files, output with line numbers
用法gn [options] <pattern> <filename1> <filename2> ...
Script m1 grep -n $*
解釋 可以用來檢視哪些檔案含有某一字串, 這個 script 很單純的將使用者所下的grep 指令加上 -n 選項而已。 讀者如果會常常用到時,建議製作成指令以便重複使用,省點打鍵盤的功夫。

 

功能 check the tail lines of your mail box
Script m2 tail -100 /usr/spool/mail/uname
解釋 假設系統將各人的信箱放在 /usr/spool/mail/yourname
這個指令將信箱中的最後100行印出來,
可用來檢查是否有新信件進來。
新信件如有附加檔或encoded text,不容易檢視內容。

 

功能 double space a text file
Script m3 sed G <filename>
解釋 G 是 sed 的指令,將 buffer 的內容加在每一行後面
因為buffer內的初始值是空的,其效果等於 在每一行文字後面加上一個空行。
請注意,G 是 sed 內的一個一般性指令,並非特意為double space的功能 所設計的。

 

功能 count the number of lines for a file, number only
Script m4 wc -l $1 | cut -c1-8
解釋 wc 這個指令會列出一個檔案的行數、字數、及字元數,其格式 隨系統而不同,使用者必須依據實際情況調整。 在很多script中都會用到檔案的行數作為參數,所以有必要 設計一個指令將所需要的資訊從wc 這個指令所輸出的一堆資訊中提出來。

 

功能 產生從1開始的數目序列
用法count <number>
Script m5a
   count=1
   while [ $count -le $1 ]
   do
       echo $count
       count=`expr $count + 1`
   done
Script m5b 如果你的系統有支援 $(( ... )) 這種運算的話,這個script 可以寫得簡單一些。
   count=1
   while [ $count -le $1 ]
   do
       echo $((count++))
   done
Script m6
解釋 m6
  1   head -$1 <longfile> 這個指令將 <longfile> 的前 $1 行抓出來,而
  2   cat -n 會把讀到的資料加上行數送到 STDOUT,
  3   而 cut -c1-6 則把前六個 character「砍」下來,正好是行數,數字 1 至 $1。

使用者可以自己找一個或製作一個長檔案作為 longfile。
Script m7 head -$1 <longfile> | awk "{print NR}"
Script m8 head -$1 <longfile> | perl -p 'print $.'
上面這些另類檔案之成功與否,依賴著 longfile 的大小, 是個漏洞,因此並非是嚴謹的程式,不能拿來作為正式的應用程式使用, 本文舉這個例子,只是用來展示「另類」的運算邏輯之用。

功能 產生一個區間的數目序列
用法numberseq <begin-number> <end-number>
Script m5b
   count=$1
   while [ $count -le $2 ]
   do
       echo $((count++))
   done

功能 產生一個區間的等加序列
用法numberseq <begin-number> <end-number> <skip-number>
Script m5c
   count=$1
   while [ $count -le $2 ]
   do
       echo $count
       count=`expr $count + $3`
   done
Script m5d
   count=$1
   while [ $count -le $2 ]
   do
       echo $count
       echo $((count+=3)) > /dev/null
   done

 

功能 Instant Message
Script m9 echo "Hello!" > /dev/ttyxx
Script m10 cat filename > /dev/ttyxx
解釋 m9,m10 Script m9 將"Hello!"字串送到終端機 ttyxx 上, 而 Script m10 將檔案 <filename> 的內容送到終端機 ttyxx 上, 這就是一種instant message。
終端機在Unix 裡被視為一個檔案,其權限通常是對所有使用者開放的, (當然使用者可以關閉權限), 任何使用者可以將任何資訊送進這些檔案,其效果等於將資訊展現 在那個終端機上。使用者可以利用 who 這個指令,找出收訊者的終端機 編號。(uid 後面即是 terminal id, 將前面加上 /dev/ 即可得到對應的檔名)。
Script m11 cat < /dev/ttyxx
解釋 m11 既然別人的終端機可以寫入,那當然也可以讀,這個指令 可以讓人偷窺他人在終端機上所敲的任何鍵!! 不過,別慌,系統的初始設定應該會將他人讀這個檔案的權限關閉, 只有 super user 可以讀得到這個檔案。

 

功能 search a file recursively
Script m12 find $HOME -name <pattern> -print
Script m13 find . -name <pattern> -print
解釋 Script m12 從 $HOME 開始往下搜尋名為 <pattern> 的檔案,
Script m13 從現在的工作目錄開始往下搜尋名為 <pattern> 的檔案。
<pattern>裡可以含有萬用字元,但必須包含在""之內,以免被 shell 在執行之前即被展開。

 

功能 如何讓程式在logout以後還能繼續執行
Script m14 nohup command [ arguments ] &

 

功能 How to make a "script" to judge which "shell" we are in?
Script m15 echo $SHELL

 

功能 finding files that are less than a day old
Script m16 find / -amin +120 ...
Script m17 find . -newer <filename> -print
Script m18 find . -mmin +120 -type f -exec rm -r {} \;

 

 

功能 分割檔案 split
Script m19a split <filename>
解釋 將一個檔案分成數個 1000 行的檔案
Script m19b split -b 1m <filename>
解釋 將一個檔案分成數個 1mb 的檔案

 

功能 delete empty file
Script m20 find / -size 0 \(-name \*.dat -o -name sh\*.dat \) -exec rm -f {} \;
Fri Feb 28 16:24:53 CST 2014 Untitled Document
為一堆檔案更改檔名

 

功能 change file names for a group of files
Script f1
 for i in Image*.jpg
 do
 mv $i nccu$i
 done
解釋 這個 script 將以檔名為 Image 開頭的 JPG 影像檔全部更改檔名,在 原檔名之前加上"nccu"字串。 當然,如果嫌檔名太長的話,可以加幾個指令,可以做得更好。
如果要將數位相機照得的一堆影像檔改個較有意義的檔名時, 這非常好用。

 

功能 change file names for a group of files
Script f2
  ls | sed 's/..*/mv & &/' > script
  vi  script
  sh script
  1   列出所有要改的檔案
  2   match to 任意字串
每一個檔案名都符合條件
  3   將 2 所找到的字串,填入於此,
對應於一個 fname 的檔名,sed 的指令為 s/fname/mv fname fname/
  4 & 5   ls 得到的檔名,成為搜尋的字串,進而成為替代字串
解釋這個 script 比較general, 它是產生如下的編輯指令
mv <oldfilename> <oldfilename>
再叫出 vi 編輯器讓使用者自己將 第二個 <oldfilename> 改成 新檔名,如此製造一個更改檔名的 shell script, 最後再叫出 shell 來執行這個 script。 讀者可自行將vi 取代為自己喜歡的編輯器。

 

功能 將 *.txt 改成 *.csv
Script f3
for i in *.txt
do
    mv $i `basename $i .txt`.csv
done
  1   利用 basename 去掉 $i 字串最後的 .txt
  2   取得 basename 執行結果
  3   將字串 .csv 向前黏上 2 的結果而造出新檔名
Script f3a
for i in *.txt
do
    mv $i ${i%.txt}.csv
done
  1   變數 $i 在展開時,%.txt 可以去掉最後的 .txt
  2   將字串 .csv 向前黏上 1 的結果
Script f3b
for i in *.txt
do
    mv $i ${i%.*}.csv
done
  1   變數 $i 在展開時,%.* 可以去掉最後的 .txt
  2   將字串 .csv 向前黏上 2 的結果

 

功能 將 nccu.* 改成 NCCU.*
Script f4
for i in nccu.*
do
    tailname=`echo $i |  sed -e 's/^nccu\.//'`
    mv $i NCCU.$tailname
done
  1   展開 $i 送給 sed 處理
  2   match to 字串的起始
  3   保護 . 以免 sed 將其視為特殊符號
  4   保護 sed 的指令,不受干擾,增加可讀性
  5   取得執行結果,成為檔案去掉 nccu. 後的剩餘字串
Script f4a
for i in nccu.*
do
    mv $i NCCU.${i#nccu.}
done
  1   字串 NCCU. 作為新檔名的起始
  2   變數 $i 展開時,將最前面的 nccu. 去除,將剩餘字串 向前黏上 NCCU. 得到新檔名
Script f4b
for i in nccu.*
do
    mv $i NCCU.${i#*.}
done
  1   字串 NCCU. 作為新檔名的起始
  2   變數 $i 展開時,將最前面的 *. 去除,剩餘字串 之前黏上 NCCU. 得到新檔名

 

功能 rename all files in the currect directory to the lower case
Script f5
for file in *
do
        lcfile=`echo $file | tr "[A-Z]" "[a-z]"`
        mv $file $lcfile
done
解釋

  1   展開 $file 供給 tr 去轉換
  2   tr 將展開的字串轉成小寫(lower case)
  3   取得轉換結果成為新檔名,放入變數 lcfile
Fri Feb 28 16:24:53 CST 2014 Untitled Document
Filtering and Conversion

 

功能 convert text file in DOS format into UNIX format
Script c1
   ex $1 <<%       
   1,\$s/^M\$//     
   w              
   %             
解釋 在script 中,^M 是一個控制字元,請 不要誤解成 '^' 及 'M' 兩個字元。
此外,shell 將"<<%" 與 "%" 兩個符號之間的 text 送給 ex 作為使用者之 鍵盤輸入,由於 $ 這個字元在 shell 中是特殊字元,必須 加上escape字元,其原始 editing script 如下:

1,$s/^M$// 
w     

 

功能 filtering out words: is, this, a
Script c2 sed "s/this//;s/is//;s/a//;s/ *//g"
解釋
Input: this is a dumb question
Desired Output: dumb question 

if you want to filter 'is' but not "isn't", that wouldn't work; you could still use sed, but I think I'd use perl so that I don't have to code 3 sed substitutions for every word:

Script c3 sed "s/this//;s/is//;s/a//;s/ *//g"
Script c4 perl -p -e 's/(^|\s+)is(\s+|$)//g;s/(^|\s+)this(\s+|$)//g;'
Script c5 perl -p -e 's/(^|\s+)(is|this)(\s+|$)//g;'

 

功能 converting string
9600012301ADTA02ATDT03AATA04TADD05TDAA06ABCD
into the following format:
 96000123
 01ADTA
 02ATDT
 03AATA
 04TADD
 05TDAA
 06ABCD
Script c6
sed 's/\([0-9][0-9][A-Z][A-Z][A-Z][A-Z]\)/\
\1/g'
Command c6-2 perl -p -e 's/(\d\d[A-Z][A-Z][A-Z][A-Z])/\n$1/g'
解釋 It reads "insert newline before every occurrence of two numbers followed by four uppercase letters."

If spaces/tabs on a line count as a blank line, then you need a more complicated expression.

 

功能 swap the first two columns
sed/ex Script c7 %s/^\([^ ]*\) \([^ ]*\)/\2 \1/
解釋 注意 \( \) \1 \2 在 ex/sed 裡的意義
awk Script c8 awk '{print $2 $1}'
解釋 注意 ' ' 這對引號在這裡的用處,它可以避免shell 將$1, $2 當成變數。讀者應盡可能熟悉 ' ', " ", 及 ` ` 這幾對引號的用法。

 

功能 convert a file into 2 column
Script c9 pr -t -l66 -w80 -2 <filename>
現在有 Winword 作為文件的編輯程式,在Unix將文件做 兩欄式的編排之需求已經大不如前。

 

功能 interlave a single column file into 2 column
Script c10 (oddeven)
cat $1 | while read odd
do
   read even
   echo $odd $even
done
Fri Feb 28 16:24:53 CST 2014 Untitled Document
Cut a block of lines from a file
功能 檔案片段之截取 (cut a block of lines)
用法gl <beginline> <endline> <filename>
Script b1 sed -n -e "$1,$2p" $3
Script b2
if [ "$2" -lt "$1" ] #測試 $2 是否大於 $1
then
    echo $2 smaller than $1
exit
fi
QuitPoint=`expr $2 + 1` #設定要終止印出的行數
sed -n -e "$1,$2p #印出需要的檔案片段
${QuitPoint}q" $3 #終止sed, 避免繼續執行的最後一行
解釋 b1,b2 使用 Script b1,b2 ,使用者要提供開始及結束之行數 Script b2 比 Script b1 快,當awk 將輸入檔案讀入時,讀到 <endline> 時就停止,而Script b1 則會一直讀到最後一行,當檔案很大時會浪費很多時間。
Script b3 awk '/<beginline>/,/<endline>/' <filename>
解釋 b3 使用這個指令時使用者不是輸入行數,而是 輸入含有 <beginline> 字串的行及 含有 <endline> 字串的行。
Script b4
    awk '{if ( $0=="<beginline>") \
    flag=1 \
    else { if($0=="<endline>") \
    flag=0 \
    if (flag==1) \
    print}}' <filename>
解釋 b4 同上,但輸出時不包括 <beginline>以及<endline>這兩行。
輸入資料每一行只有一個 number時
Script b4
    awk '{if ( $2=="<beginline>") \
    flag=1 \
    else { if($2=="<endline>") \
    flag=0 \
    if (flag==1) \
    print}}' <filename>
解釋 b5 同上,但比對輸入資料第二欄位內含的數字

 

功能 delete a block of lines from a file
用法dl <beginline> endline> <filename>
Script b5
   if [ "$2" -lt "$1" ]  |   #測試 $2 是否大於 $1 
then     echo $2 smaller than $1     exit fi
cp $3 tmp.o echo "$1,$2d w" > script ex $3 < script
解釋 這個script 先製作一個編輯指令檔,再利用它來編輯原文, 備份留在 tmp.o

 

功能 Delete all lines that contain some string and output to STDOUT
Script b6 grep -v "string" <filename>

 

功能 delete blank lines from a file and output to STDOUT
Script b7 egrep -v '(^$)' <filename>
解釋 注意 -v 在 egrep 裡的作用,而 '^$' 在 regular expression 中代表空行

 

功能 replace a block of lines of a file
用法rl <beginline> <endline> <filename> <filename>
Script b8
if [ "$2" -lt "$1" ] #測試 $2 是否大於 $1
then
    echo $2 smaller than $1
    exit
fi
mv $3 tmp.o  
begin=$1 #被取代的第一行
end=$2 #被取代的最後一行
head -$((--begin)) tmp.o > $3 #取得被取代區塊之前面
cat $4 >> $3 #將代換的檔案插入空出的位置
sed -n -e "$((++end)),\$p" tmp.o >> $3 #取得被取代區塊之後面
Fri Feb 28 16:24:53 CST 2014 Untitled Document
GrepDom - Basic
   
我們常常需要處理多欄文字檔,例如大量的實驗數據,而 常常需要根據某欄位的值作為條件抽出該列,甚至該列的某些欄值。 就像關聯式的資料庫裡的 Selection 加 Projection 的動作。 可惜 grep 並不能指定比對的欄位,只能利用 awk 這類工具來處理。 例如:
 
輸入資料
10 20 30 40
30 40 40 80
50 70 40 20
5 30 30 10
awk '$2 == 30' inputfile 

#第二欄如果是30則印出該列,結果:5 30 30 10

awk '$2 == 30 {print $4, $1}' inputfile 

#第二欄如果是30則印出該列的第四及第一欄,結果:10 5

   
而下面這個 script 則先產生一個 awk script , 再用這個 awk script 來處理輸入資料,結果相同。

echo '$2 == 30 {print $4, $1}' > awk.script
awk -f awk.script inputfile
Fri Feb 28 16:24:53 CST 2014 Untitled Document
GrepDom - 可任意指定比對的欄位
 
如果使用者希望能彈性的指定比對的欄位以及印出的欄位, 就需要比較高明的 script

Take the first argument as the column position, the second as the given pattern, and the third as input file to filter out those lines whose value at the given column matches to the given pattern.

SYNOPSIS grepdom column_num pattern infile
Usage grepdom 3 pat1 infile

 
#Script grepdomA
awk "\$$1 == $2" $3
 
#Script grepdomB
echo "\$$1 == $2" > awk.script
awk -f awk.script $3

這個 script 根據使用者給定的參數動態的產生一個
awk script, 再用 這個 awk script 來處理輸入資料。

輸入資料 執行指令 實際執行 script 結果
10 20 30 40
30 40 40 80
50 70 40 20
5 30 30 10
grepdomA 2 40 input
awk '$2 == 40' input
30 40 40 80
grepdomB 2 30 input
echo '$2 == 30' > awk.script
awk -f awk.script input
5 30 30 10
 
為增加實用性,可增加指定 field delimiter 的 option
Fri Feb 28 16:24:53 CST 2014 Untitled Document
GrepDom - 可任意指定比對的欄位及輸出欄位
 
Same as previous version, but with the 4th and after arguments as the columns to be printed
It can be viewed as a Selction after a Projection operations in Relational database.
SYNOPSIS grepdom column_num pattern infile col1 col2 ...
Usage grepdom 3 pat1 infile col1 col2 col3 ...
 
輸入資料
10 20 30 40
30 40 40 80
50 70 40 20
5 30 30 10
執行指令 執行 awk script 結果
grepdom 2 40 input 2 3 4 $2 ~ /40/ {print $2,$3,$4} 40,40,80
grepdom 2 30 input 4 2 3 $2 ~ /30/ {print $4,$2,$3} 10,30,30
grepdom 1 50 input 2 4 $1 ~ /50/ {print $2,$4} 70,20
grepdom 4 40 input $4 ~ /40/ 10,20,30,40
 
Script 1 (使用迴圈打造 Ex Script,再用 Ex script 編輯 Awk Script)
因為輸出欄位是使用者任意指定的,並非固定不變動, 因此,awk script 不能一成不變,必須隨著使用者給定而變動, 因此,必須設法動態的製造一個 awk script,在下面這個shell script中, 我們先製造一個 ex script,再利用這個 ex script 來修改 awk script, 最後再利用所得到的 awk script 來處理輸入資料。 為避免太複雜的script,我們將輸入與輸出欄位的delimiter 都預設在 script 中,讀者可自由修改,符合自己的需要。
 
     1 FileName=$3 
     2 echo 'BEGIN{FS=" "; OFS=",";}' >awk.script 
     3 echo "\$$1~/$2/" >>awk.script 
     4 shift 3  #捨棄前面三個參數,剩下輸出欄位參數 
     5 
     6 if [ $# -ge 1 ]  #檢查是否有輸出欄位參數 
     7 then 
     8    echo '2s/$/{print /'> ex.script 
     9    for i 
     10    do 
     11       echo "2s/\$/\$$i,/">> ex.script 
     12    done 
     13    echo '2s/,$/}/'>> ex.script 
     14    echo 'w' >> ex.script 
     15    ex awk.script < ex.script 
     16 fi 
     17 awk -f awk.script $FileName 
Line Script 執行指令
grepdom 2 30 input 4 2 3
2 awk BEGIN{FS=" "; OFS=",";}
3 awk BEGIN{FS=" "; OFS=",";}
$2 ~ /30/
8 ex 2s/$/{print /
14 ex
2s/$/{print /
2s/$/$4,/
2s/$/$2,/
2s/$/$3,/
2s/,$/}/
w
15 awk BEGIN{FS=" "; OFS=",";}
$2 ~ /30/ {print $4,$2,$3}
17 結果 10,30,30
 
Script 2 (使用迴圈打造一個變數,再展開此變數加進 Awk Script)
Script 1 中,ex.script 的運作,有點不容易看清楚,Script 2 直接將 awk.script 的第二行放在一個變數中隨著迴圈而增長,比較容易看清楚。
 
     1 FileName=$3 
     2 echo 'BEGIN{FS=" "; OFS=",";}' >awk.script 
     3 arg="\$$1~/$2/"
     4 shift 3  #捨棄前面三個參數,剩下輸出欄位參數 
     5 
     6 if [ $# -ge 1 ]  #檢查是否有輸出欄位參數 
     7 then 
     8    arg="$arg {print "
     9    for i 
     10    do 
     11         arg="${arg}\$$i," 
12 done 13 echo "${arg%,}}" >> awk.script 14 fi 15 awk -f awk.script $FileName
Line Script
& arg
執行指令
grepdom 2 30 input 4 2 3
2 awk BEGIN{FS=" "; OFS=",";}
3 arg $2 ~ /30/
8 arg $2 ~ /30/ {print
11 1st round arg $2 ~ /30/ {print $4,
11 2nd round arg $2 ~ /30/ {print $4,$2,
11 3nd round arg $2 ~ /30/ {print $4,$2,$3,
13 awk BEGIN{FS=" "; OFS=",";}
$2 ~ /30/ {print $4,$2,$3}
15 結果 10,30,30
  1   變數 arg 的範圍
  2   展開變數 arg 時將最後的 , 刪掉
  3   將 } 向前黏上 2 的結果
  1-3   將變數 arg 內含字串的最後 , 取代為 }
 
Script 3 (不用迴圈)
可以不使用迴圈就可以打造出期望的 arg (Script 2 的一個變數)
 
     1 FileName=$3
     2 arg="\$$1~/$2/"
     3 shift 3  #捨棄前面三個參數,剩下輸出欄位參數 
     4    [ $# -ge 1 ] && arg="$arg {print \$`echo $* | sed 's/ /,\$/g'`}" 
5 awk "$arg" $FileName
Line Script & arg 執行指令
grepdom 2 30 input 4 2 3
2 arg $2 ~ /30/
4 arg $2 ~ /30/ {print $4,$2,$3}
5 結果 10 30 30
   
第四行之解釋 (以 grepdom 2 30 input 4 2 3 為例)
  1   檢查是否有指定輸出欄位   7 抓出 echo $* | sed 's/ /,$/g' 的結果
  2   若有指定輸出欄位,則執行 3   8 全部的輸入變數,以空白隔開,得到 4 2 3
  3   將後面的字串放進 arg   9 以 sed 將 $* 中的空白全部改成 ,$,得到 4,$2,$3
  4   利用 " " 將字串包起來 10 字串 $2 ~ /30/ {print $
  5   保留 $ 字元,避免被當成變數 11 字串 }
  6   利用 ' ' 將送給 sed 的指令包起來
's/ /,$/g'
9-11 $2 ~ /30/ {print $4,$2,$3}
 
Script 4 (不用迴圈)
如果輸出的欄位次序不變(與輸入資料欄位次序相同), 可用 cut 來簡化 script
 
     1 FileName=$3 
     2 echo 'BEGIN{FS=" "; OFS=",";}' >awk.script 
     3 echo "\$$1~/$2/" >>awk.script 
     4 shift 3  #捨棄前面三個參數,剩下輸出欄位參數 
     5 
     6 if [ $# -ge 1 ]  #檢查是否有輸出欄位參數 
     7 then 
     8    arg=`echo $* |sed 's/ /,/g'` 
     9    awk -f awk.script $FileName |cut -d',' -f$arg
     10 else 
     11    awk -f awk.script $FileName 
     12 fi 
Line Script & arg 執行指令 grepdom 2 30 input 4 2 3
2 awk BEGIN{FS=" "; OFS=",";}
3 awk BEGIN{FS=" "; OFS=",";}
$2 ~ /30/
8 arg 4,2,3
9.1 awk 輸出 5,30,30,10
9.2 cut cut -d',' -f4,2,3
9 最後結果 30,30,10
11   如果沒指定輸出欄位之結果
5,30,30,10
 
Script 5 (最簡版)
如果輸入資料是從 STDIN 進來,使用 default field separator,可以更為簡單
     1 arg="\$$1~/$2/"
     2 shift 2  #捨棄前面二個參數,剩下輸出欄位參數 
     3 [ $# -ge 1 ] && arg="$arg {print \$`echo $* | sed 's/ /,\$/g'`}" 
     4 cat | awk "$arg"
Fri Feb 28 16:24:53 CST 2014 Untitled Document
FTP
功能 batch ftp a file
Script p1
   ftp $1 <<%
   lien
   binary
   put $2   (OR get $2)
   quit
   %

 

功能 batch ftp many files
Script p2
   echo "ftp $1 <<%
   lien
   binary" > script
   for i 
   do
     echo "put $i"
   done >> script
   echo "quit
   %" >> script 
   sh script
Fri Feb 28 16:24:53 CST 2014 Untitled Document
Math: Compute Average, Maximum and Minimum
功能 compute average of a column
用法 avg <column> <filename>
Script ma1
  awk "{sum += \$$1;}
       END {print sum/NR} "  $2

 

功能 compute the maximum of any column
用法 max <column> <filename>
Script ma2
awk "
    BEGIN { MAX = -999999}
    { 
      if ( \$$1 > MAX)
	 MAX = \$$1 
    }
    END {print MAX}"  $2
Fri Feb 28 16:24:54 CST 2014 Untitled Document
Spelling Tools

 

功能 find an English word
用法 (例)wordhelp con v en t
( e.g. looking for the word "convenient")
Script s1
pat=$1;   
shift
grep "^$pat"  /usr/lib/dict/all  | mgrep $*
解釋 很多Unix 系統都有個spell的指令,這個指令一定會用到 一個字典,其中含有大部分的英文單字,我們可以運用 這個檔案來做很多跟字典有關的工作。 使用者可以嘗試找找這個檔案 /usr/lib/dict/all。
wordhelp 這個script 是筆者最常用的script,寫英文文章時幫助非常大。 我們對一個英文字的拼法不熟時,查一般的字典也無從下手, 可能要試很多次,將一部字典翻來覆去才能找到要查的字。 wordhelp 這個 script 可讓使用者輸入一個英文字的某些片段,就可以將含有 這些片段的英文字列出來,而同時含有這些片段的英文單字 屈指可數,很容易就可挑出自己想找的單字。

請注意,這個Script 出現了一個罕見的 shift 指令,這是 shell 裡一個重要的指令,可以將使用者在command line 下的參數做個變動, 將 $1 捨棄,而將後面的 $2, $3, $4 等往前移動,如此,在script 中就可以將原代表所有參數的變數符號"$*"用來代表 $2, $3, $4 等參數。

 
Homework: 設計一個可以幫助 word puzzle (填字遊戲) 的指令?

 

功能 grep with multiple patterns
用法mgrep <pat1> <pat2> <pat3> ...
Script s2
if [ $# -ge 1 ] #檢查是否有輸入待比對的字串
then  
arg=`echo $* | sed -e 's/ / | grep /g'` #sed 將所有相鄰輸入字串中間插入 '| grep '
arg="cat | grep $arg" #變數arg放入一個如此字串 'cat | grep pat1 | grep pat2 | grep pat3 ....'
eval $arg #將變數 arg 之內容當成指令執行
fi  

Alternative by fgrep
if [ $# -ge 1 ]
then
arg=`echo $* | sed -e 's/ / | /g'`
arg="cat | fgrep \"$arg\""
eval $arg
fi
解釋 Script s2 會將STDIN含有數個指定字串的「行」抓出來, 使用者可輕易更改這個script,讓他可以grep 更多的pattern。 對於常常使用的人,可省下許多時間。下面的 spellcorrect 會用到 這個關鍵的 script。

 

功能 Spelling Corrector
用法spellcorrect <filename>
Script s3
   1 spell $1 > 1.o
   2 comm -13 1.o excludedwords > 2.o
   3 sed 's/..*/1,$s\/&\/&\/g' 2.o > script
   4 vi script
   5 ex $1 < script
1   將輸入的檔案利用spell找出字典沒有的字
2   利用 comm -13 將使用者的專有字剔除
3   將剩下的錯字製造出一個編輯指令檔, 對應每一個錯字,有一行 1,$s/oldword/oldword/ 編輯指令
4   叫出vi (可用其他編輯器取代) 來讓使用者將該編輯指令檔編輯成一個可以更正錯字的編輯指令檔, 對應每一個錯字,有一行 1,$s/oldword/newword/ 編輯指令
  5   叫出ex 編輯器利用此編輯指令檔將原文裡的錯字改掉
解釋
在Unix 上寫英文文章時,這個script 可以幫忙更改錯字, 省下很多麻煩的編輯動作,非常有用。
問題利用這個script時,有時候要注意編輯指令檔的正確性, 萬一發生錯誤時,可能會破壞原檔案,改到不該改的字。 例如,如果文章裡有個 "th"的字被挑出來,使用者如果 將這個指令 1,$s/th/th/g 改成 1,$s/th/the/g 的話,後果將會很嚴重。

此外,ex 是一個 atomic 的程式, (do all or do nothing), 如果其中有一個編輯指令失敗,最後的 w 將不會作用,導致 執行失敗。 例如,下面的編輯指令會失敗。


1,$s/systen/system/g
1,$s/systens/systems/g
w
讀者應該在editor 內將編輯指令檔改成下面這樣才行:

1,$s/systen/system/g
w
Fri Feb 28 16:24:54 CST 2014 Untitled Document
Scripts for HTML
功能 generate a color table
Script h1
for R in 00 88 ff 
do
   echo "<TABLE>"
   for G in 00 88 ff 
   do
      echo "<TR>"
      for B in 00 88 ff 
      do
      echo "<TH bgcolor=#$R$G$B>
      <font size=3 color=BLACK>$R $G $B<br>
      <font size=3 color=#$R$G$B>$R $G $B</TH>"
      done
      echo "</TR>"
   done
   echo "</TABLE>"
done
解釋 本 script 會產生一段 HTML 碼,這段 HTML 碼在瀏覽器上會 顯示一個色表,裡面有各種顏色及其對應的 RGB 碼, 使用者可輕易改寫,增加更多的顏色。
結果
00 00 00
00 00 00
00 00 88
00 00 88
00 00 ff
00 00 ff
00 88 00
00 88 00
00 88 88
00 88 88
00 88 ff
00 88 ff
00 ff 00
00 ff 00
00 ff 88
00 ff 88
00 ff ff
00 ff ff
88 00 00
88 00 00
88 00 88
88 00 88
88 00 ff
88 00 ff
88 88 00
88 88 00
88 88 88
88 88 88
88 88 ff
88 88 ff
88 ff 00
88 ff 00
88 ff 88
88 ff 88
88 ff ff
88 ff ff
ff 00 00
ff 00 00
ff 00 88
ff 00 88
ff 00 ff
ff 00 ff
ff 88 00
ff 88 00
ff 88 88
ff 88 88
ff 88 ff
ff 88 ff
ff ff 00
ff ff 00
ff ff 88
ff ff 88
ff ff ff
ff ff ff
這個 Script 裡 R,G,B 的參數如果改為 00, 33, 66, 99, CC, FF,就可以 產生一個展示216安全網頁顏色的 HTML 檔
Fri Feb 28 16:24:54 CST 2014 Untitled Document
Code Generator 1
Page Show
 
產生 Hyper links to 24 種不同的換頁效果網頁

<head>
<title>網頁切換效果</title>
<meta http-equiv="Page-Enter" content="   revealTrans(Duration=3.0,Transition=0) ">
</head>
<body background="image.jpg">
</body>
1.產生 0-23 一組數字 > count (Can be done manually too)
2. 利用 count 產生一個 script, copy 24 個jpg file 並 rename to image0.jpg, image1.jpg,... image23.jpg
3. 製造一個 含有上述 code 的 template 檔
4. 利用 count 及 template 產生 24 個不同換頁效果的檔案
5. 利用 count 產生一個HTML 檔,含有24 個Hyperlink 連到24個產生的檔案。
 
Script for Step 4 and 5
echo "<HTML><TABLE border=1>"
for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 
do
f=pageshow$i.htm
sed -e "s/=0/=$i/" -e "s/image/&$i"/ template.htm > $f
echo "<TR><TH><A href=$f><font size=3>$i</A>"
done
echo "</TABLE></HTML>"
Fri Feb 28 16:24:54 CST 2014 Untitled Document
Code Generator 2
To generate strings.xml for Eclipse/Android
 
Input string definition
stringvar1 This is String Variable 1
stringvar2 This is String Variable 2
stringvar3 This is String Variable 3
stringvar4 This is String Variable 4
stringvar5 This is String Variable 5
stringvar6 This is String Variable 6
 
Output to strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
 <string name="stringvar1">This is String Variable 1</string>
 <string name="stringvar2">This is String Variable 2</string>
 <string name="stringvar3">This is String Variable 3</string>
 <string name="stringvar4">This is String Variable 4</string>
 <string name="stringvar5">This is String Variable 5</string>
 <string name="stringvar6">This is String Variable 6</string>
</resources>
 
Script
echo '<?xml version="1.0" encoding="utf-8"?>
<resources>'
while read a b 
do
echo ' <string name="'$a'">'$b'</string>'
done < $1
echo '</resources>'
Fri Feb 28 16:24:54 CST 2014 Untitled Document
FAQ
Delete files with odd names
 
Problem
   
我做網站上傳檔案'後來改名稱'結果檔名變成前一個為空白就是 _INDEX.HTM-前面那條線是空白'無法刪除'
 
Solution
   
先移到跟那個檔案同一個目錄下 然後試試rm ./檔名吧 如果不可以的話....才試試rm -ir .(這樣比較危險一點) rm -r .的意思是砍掉目前目錄以及其下的子目錄及檔案 加上i的話,系統會在砍掉目錄或檔案前先詢問y or n 回答y才會砍,回答n就不砍,你看到要砍的那個檔案再按y 其他都按n(小心不要按錯了,砍了救不回來的)
ftp 抓子目錄..
 
unix 有沒有甚麼ftp軟體 可以抓子目錄阿...
   
ncftp:
   
ncftp> get -R dir_name
   
wget. GNU software.

An AWK problem
   
I am looking through a bunch of files in a directory. The files I am trying to isolate contain the "046*" in the 3rd record and the string "TOWER GROUP" in the 6th record. There are many files to go through and I have tried working with 'grep -l' but that only works in an ideal situation. The command 'awk' is useful but how do I display the contents of the entire file if the conditions are met.


BEGIN { FS = "," }
$3 ~ /046\*/ && $6 == "TOWER GROUP" {
  while( (getline < FILENAME) > 0)
    print
  close(FILENAME)
}

Question : Comparing Number
   
I'm trying to compare two numbers. If the day of the month is less than 10 then echo "larger". Otherwise, echo "smaller".

#!/bin/sh
num=date" +%d"
echo "\n $num"
if expr "$num" \> 10
then
echo "larger"
else
echo "smaller"
fi
Fri Feb 28 16:24:54 CST 2014