戲說 Unix 馬蓋先 (V3)
 

1. 話說從頭

 

2. Shell Programming 之優缺點
 
任何一種程式語言都有其最適用的情況及其罩門,Unix Shell Programming 也 難逃此宿命。它有幾項優點:

1. Script 都是純文字檔,不被特定軟體綁住
2. Shell script 不需編譯即可使用,非常容易移植到不同的 Unix
3. 適合用於開發以字串處理及檔案管理為主的簡易小軟體
4. 因開發耗時極短,玩家可隨時根據自己的需求動手開發或更改

 
1. Script 都是純文字檔,不被特定軟體綁住

 
2. Shell script 不需編譯即可使用,非常容易移植到不同的 Unix 系統下執行

 
3. 適合用於開發以字串處理及檔案管理為主的簡易小軟體

 
4. 因開發耗時極短,玩家可隨時根據自己的需求動手開發或更改

 

缺點當然是免不了:

1. 執行效率較差
2. 力有未逮之時
3. 漏洞難免

 
1. 執行效率較差

 
2. 力有未逮之時

 
3. 漏洞難免

 

3. 學習 Unix Shell Programming 之方法

1. 熟悉 Unix 上各種基本指令及小型工具程式
2. 盡量熟悉 Regular Expression
3. 熟悉各種特殊符號及其用法
4. 熟悉 Unix 上各種系統檔案的路徑
5. 熟悉 Unix 基本精神
6. 熟悉 Unix 程式設計的一些習慣,並盡量配合
7. 多練習,多使用
8. 盡快學會一個 Unix 上具有regular expression的編輯器
 
1. 熟悉 Unix 上各種基本指令及小型工具程式

 
2. 盡量熟悉 Regular Expression

 
3. 熟悉各種特殊符號及其用法

 
4. 熟悉 Unix 上各種系統檔案的路徑

 
5. 熟悉 Unix 基本精神

 
6. 熟悉 Unix 程式設計的一些習慣,並盡量配合

 
7. 多練習,多使用

 
8. 盡快學會一個 Unix 上具有regular expression的編輯器

 

4. Shell Script 設計小秘訣

1. 定期備份,隨時備份要更改的檔案
2. 慎重選用適當的工具程式
3. 盡量自動化
4. 不要勉強自動化
5. 適時搭配 PC 視窗系統
 
1. 定期備份,隨時備份要更改的檔案

 
2. 慎重選用適當的工具程式

 
3. 盡量自動化

 
4. 不要勉強自動化

 
5. 適時搭配 PC 視窗系統

 

5. 一些實用的 Shell Script 實例

 

 
5.1 簡單的 script

 

功能 抽取檔案中含有某字串的"行",並列出行數
用法gn [options] <pattern> <filename1> <filename2> ...
Script m1 grep -n $*
解釋 可以用來檢視哪些檔案含有某一字串,並列出所在行數。 這個 script 很單純的將使用者所下的grep 指令加上 -n 選項而已。 因為很多其他的script 會需要知道某些字串在檔案中的位置,使用頻率很高, 建議製作成指令以便重複使用,省點打鍵盤的功夫。

 

功能 查看信箱內最後100行資訊
Command m2 tail -100 /usr/mail/yourname
解釋 假設系統將各人的信箱放在 /usr/mail/yourname
這個指令將信箱中的最後100行印出來,
可用來檢查是否有新信件進來。
現在的 email 經常有不同的中文編碼方式,或帶有非純文字 的附加檔,如有這種情況,看到的可能是亂碼。這個 script 對中文的使用者而言,現在幾乎是無用武之地了。

 

功能 將檔案變成 double space
Command m3 sed G <filename>
解釋 G 是 sed 的指令,其作用是將 buffer 的內容加在輸入檔的 每一行後面,但因為buffer內的初始值是空的,其效果等於在每一行 文字後面加上一個空行。
請注意:G 是 sed 內的一個一般性指令,並非特意為double space的功能 所設計的。

 

功能 計算檔案的行數
Script m4

wc -l $1 | cut -c1-8
 
解釋 wc 這個指令會列出一個檔案的行數、字數、及字元數,其格式 隨系統而不同,使用者必須依據實際情況調整。 在很多script中都會用到檔案的行數作為參數,所以有必要 設計一個指令將所需要的資訊從wc 這個指令所輸出的一堆資訊中提出來, 提供給其他指令使用。
各個不同的 Unix 系統對於 wc 這個指令可能各有不同的輸出格式,使用者 當根據實際情況設計這個script。

 

功能 產生從1開始的數目序列
用法count <number>
Script m5a
   count=1
   while [ $count -le $1 ]
   do
       echo $count
       count=`expr $count + 1`
   done
Script m5b shell 支援數學運算的能力很弱,但 如果你的系統有支援 $(( ... )) 這種運算的話,這個script 可以寫得簡單一些。
   count=1
   while [ $count -le $1 ]
   do
       echo $((count++))
   done
Script m6
解釋 m6 假設 <longfile> 是一個超過 $1 行數的檔案,
  1   head -$1 <longfile> 這個指令將 <longfile> 的前 $1 行抓?X來,而
  2   cat -n 會把讀到的資料加上行數送到 STDOUT,
  3   而 cut -c1-6 則把前六個 character「砍」下來,正好是行數,數字 1 至 $1。 當然,如果longfile 的行數小於 $1, 這個script 會失敗。 使用者可以自己找一個或製作一個長檔案作為 <longfile>。

Script m7 head -$1 <longfile> | awk "{print NR}"
Script m8 head -$1 <longfile> | perl -ne 'print "$.\n"'
上面這些另類檔案之成功與否,依賴著 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
 
Generate 26 English Characters

Take a file that has many English words
Use Vi to split words into characters
Use spell split them into a line per character
use sort -u to sort it
edit the file
use tr to obtian upper or lower case

 

功能 即時訊息 (Instant Message)
Command m9 echo "Hello!" > /dev/ttyxx
Command m10 cat filename > /dev/ttyxx
解釋 m9,m10 Command m9 將"Hello!"字串送到終端機 ttyxx 上, Command m10 將檔案 <filename> 的內容送到終端機 ttyxx 上, 這就是一種instant message(通訊範圍侷限於同一系統的不同使用者, 而非網路上不同系統上的使用者)。

終端機在Unix 裡被視為一個檔案,在早期其權限通常是對所有使用者 開放的,(當然使用者可以關閉權限), 任何使用者可以將任何資訊送進這些檔案,其效果等於將資訊展現 在那個終端機上。

'/dev/ttyxx'是代表終端機的檔案, 使用者可以利用 who 這個指令,找出收訊者的終端機 編號。uid 後面即是 terminal id, 鍵入 tty 指令,即可得知系統 如何將你的終端機命名。

此外,各個系統為終端機檔案命名的方式各有不同,也有如此方式的: "/dev/pts/15",使用者可以從指令 tty 的輸出結果可以知道 你的系統如何為終端機檔案命名。

Command m11 cat < /dev/ttyxx
解釋 m11 既然別人的終端機可以寫入,那當然也可以讀出,這個指令 可以讓人偷窺他人在終端機上所敲的任何鍵!! 不過,別慌,系統的初始設定應該會將他人讀這個檔案的權限關閉, 只有 super user 可以讀得到這個檔案。

 

功能 搜尋檔案
Command m12 find $HOME -name <pattern>
Command m13 find . -name <pattern>
解釋 Script m12 從 $HOME 開始往下搜尋名為 <pattern> 的檔案,
Script m13 從現在的工作目錄開始往下搜尋名為 <pattern> 的檔案。
<pattern>裡可以含有萬用字元。 但必須用 "" 保護起來。

 

功能 搜尋最近一天內產生的檔案
Command m14
   find / -amin +120 ...
或 (各版本的Unix 可能不同)
   find / -amin +1 ...

 

功能 刪除空檔案
Command m20
find / -size 0  -exec rm -f {} \;
某些版本的Unix 可以如此
find / -size 0  -delete 
find 這個指令可以順便將找到的檔案加以處理,其指令是帶在 -exec 選項中,筆者不建議執行如此危險的指令,萬一下錯指令, 將會萬劫不復。 筆者建議先產生要處理的檔案,經過人工檢視,沒問題之後, 再利用這個含有檔名的檔案轉成另外一個shell script, 再拿這個 script 去執行。

 

 

功能 分割檔案
Command m15a split <filename>
解釋 將一個檔案分成數個檔案
Command m15b split -b 1m <filename>
解釋 將一個檔案分成數個 1mb 的檔案

 

 
5.2 為一群檔案更改檔名

 

功能 為一群檔案更改檔名
Script changename1

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

此外,為一群檔案更改檔名這件事,也可以很方便的使用find 的指令,利用其 "exec" 功能來簡單的做到,但是這樣做非常危險, 一有錯誤就可能導致災難性的後果,因此不建議大家使用這個方式, 寧可用比較間接,但比較安全的作法。在寫完script 之後,先檢查 清楚,測試一下,再真正執行你要做的工作。

 

功能 為一群檔案更改檔名
Script changename2

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 比 changename1 有彈性 (flexible), 它先產生如下的 script 初稿

mv <oldfilename1> <oldfilename1>
mv <oldfilename2> <oldfilename2>
mv <oldfilename3> <oldfilename3>
              
  • 第二步再叫出 vi 編輯器讓使用者自己將每一行中 第二個 <oldfilename> 改成 新檔名,如此製造一個更改檔名的 shell script, 最後再叫出 shell 來執行這個 script。
    讀者可自行將vi 取代為任何自己所喜歡的編輯器。

    這個script的功能與上個script 一樣,但更為安全,因為可以仔細檢查 執行步驟。

     

    功能 將現目錄下所有 *.txt 檔案之檔名改成 *.csv
    Script changename3
    
    for i in *.csv
    do
        mv $i `basename $i .txt`.csv
    done
     
    
    解釋

      1   利用 basename 去掉 $i 字串最後的 .txt
      2   取得 basename 執行結果
      3   將字串 .csv 向前黏上 2 的結果而造出新檔名

    `command` 相當於很多其他程式語言裡的 eval(command),亦即, 當 shell 執行到含有`command`這一行指令時,先將command 當作一個指令執行,然後將所得結果置換於原位置, 再執行那一行被修改過的指令。而執行

    basename rootname.txt .csv 
    
    執行的結果會將 "rootname.txt" 這個字串去掉尾巴,成為 "rootname" 字串,而
    mv rootname.txt  `basename rootname.txt  .txt`.csv
    
    就會變成
    mv rootname.txt  rootname.csv
    
    因此,這個script 就會將所有副檔名是 ".txt" 的所有檔案 的副檔名改成 ".csv"

    現在很多實驗室的自動測量儀器都會將測量數據以 ASICC 文字檔方式存在內部的檔案中,一個實驗作下來,可能有數十甚至 數百個數據檔案,使用者想用 Excel 等工具看這些數據時,如果能將 檔案型態從 .txt 檔改成 .csv 檔,那可省下大量的時間。當然,必須 先利用shell srcript 將分隔符號改成逗點。

    changename4
    for i in *.txt
    do
        mv $i ${i%.txt}.csv
    done
    
      1   變數 $i 在展開時,%.txt 可以去掉最後的 .txt
      2   將字串 .csv 向前黏上 1 的結果
    Script changename5
    for i in *.txt
    do
        mv $i ${i%.*}.csv
    done
    
      1   變數 $i 在展開時,%.* 可以去掉最後的 .txt
      2   將字串 .csv 向前黏上 2 的結果

     

    功能 將現目錄下所有 nccu.* 檔案之檔名改成 NCCU.*
    Script changename6
    
    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 的功能與上個script的功能類似,但所更改的卻是 "." 之前的名字。

        tailname=`echo $i |  sed -e 's/^nccu\.//'`
    
    這個指令將變數 $i 裡所含的字串(檔名),藉由sed 指令將 "nccu."刪除,剩下"." 之後的字串(通常是副檔名)。

     

    功能 將目前目錄下的所有檔案名改成小寫檔名
    Script changename7
    
    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

     

     
    5.3 轉檔程式

     

    功能 將 DOS 文字檔轉成 UNIX 文字檔
    用法dos2unix <filename>
    Script c1
    
       ex $1 <<%
       1,\$s/^M\$//
       w              
       %             
    
    解釋 這個 script 是利用 ex 裡面的編輯指令來解決 DOS/Windows .txt 檔案與 Unix 文字檔之間格式不同的問題, 在DOS 的 .txt 檔案中,行與行之間用兩個ASCII符號 (十進位010, 013) 作為間隔,而 Unix 中只需用一個間隔符號,因此這個script 利用 ex 除掉一個。
    在script 中,^M 是一個控制字元,請 不要誤解成 '^' 及 'M' 兩個字元。
    在vi 中可用 vM輸入 ^M 控制字元。
    此外,shell 將"<<%" 與 "%" 兩個符號之間的 text 送給 ex 作為使用者之 鍵盤輸入。再者,由於 $ 這個字元在 shell 中是特殊字元,必須 加上escape字元才行,其未加 escape 字元的原始編輯指令如下:
    
    1,$s/^M$// 
    w     
    
    對ex 這個編輯器而言,這個編輯指令為:「自第一行至最後一行,每一行最後 端如有^M字元,將其去除(代換成一個空字元)。

     
    功能 將下列字串
    9600012301ADTA02ATDT03AATA04TADD05TDAA06ABCD
    
    轉成下列格式:
     96000123
     01ADTA
     02ATDT
     03AATA
     04TADD
     05TDAA
     06ABCD
    
    Command 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'
    
    解釋

     

    功能 將前兩欄資料(以空白作間隔)互換順序
    sed Script c7
    
    s/^\([^ ]*\) \([^ ]*\)/\2 \1/
    
    解釋 注意 \( \) \1 \2 在 ex/sed 裡的意義
    awk Script c8
    
     awk '{print $2 $1}'
    
    perl Script c8-2
    
    perl -p -e 's/(\S+\s\S+)/$2 $1/'
    
    解釋 注意 ' ' 這對引號在這裡的用處,它可以避免shell 將$1, $2 當成變數。讀者應盡可能熟悉 ' ', " ", 及 ` ` 這幾對引號的用法。

     

    功能 將一個檔案轉成兩欄格式
    Command c9 pr -t -l66 -w80 -2 <filename>
    現在有 Winword 作為文件的編輯程式,在Unix將文件做 兩欄式的編排之需求已經大不如前。

     

     
    5.4 檔案片段之擷取

     

    功能 檔案片段之截取 (extract a block of lines)
    用法gl <beginline> <endline> <filename>
    Script b1 (gl) sed -n -e "$1,$2p" $3
    解釋 使用 Script b1,使用者要提供開始及結束之行數,sed 會將檔案 $3 讀進來,將 $1 到 $2 之間的「行」印出來,sed 會繼續執行直到 $3 全部讀完才停止。 Script b2 比 Script b1 快,當awk 將輸入檔案讀入時,讀到 <endline> 時就停止,而Script b1 則會一直讀到最後一行。
    Script b2
    
    QuitPoint=`expr $2 + 1`  #設定要終止印出的行數
    sed -n -e "$1,$2p #印出需要的檔案片段
    ${QuitPoint}q" $3 #終止sed, 避免繼續執行的最後一行
    解釋 同 b1,但比 Script b1 快,當awk 將輸入檔案讀入時,讀到 <endline> 時就停止,而Script b1 則會一直讀到最後一行。
    Command b3 awk '/<beginline>/,/<endline>/' <filename>
    解釋 b3 使用這個指令時使用者不是輸入行數,而是 輸入含有 <beginline> 字串的行及 含有 <endline> 字串的行。
    請注意,這些 script 沒有檢查 <beginline> 及 <endline> 的大小,讀者自己要小心。

     

    功能 檔案片段之刪除 (delete a block of lines)
    用法dl <beginline> <endline> <filename>
    Script b5
    
       cp $3 tmp.o
       echo "$1,$2d
       w" > script
       ex $3 < script
     
     
    
    解釋 這個script 先製作一個編輯指令檔,再利用它來編輯原文, 備份留在 tmp.o
    請注意,這個 script 沒有檢查 <beginline> 及 <endline> 的大小,讀者自己要小心。

     

    功能 刪除含有特定字串的行
    Command b6
    
    grep -v "string" <filename> 
     
     
    

     

    功能 delete blank lines from a file and output to STDOUT
    Command b7
    
    egrep -v '(^$)' <filename>
     
     
    
    解釋 注意 -v 在 egrep 裡的作用,而 '^$' 在 regular expression 中代表空行
    請注意,這個 script 沒有檢查 <beginline> 及 <endline> 的大小,讀者自己要小心。

     

    功能 檔案片段之代換 (replace a block of lines)
    用法rl <beginline> <endline> <filename> <filename>
    Script b8
    mv $3 tmp.o  
    begin=$1 #被取代的第一行
    end=$2 #被取代的最後一行
    head -$((--begin)) tmp.o > $3 #取得被取代區塊之前面
    cat $4 >> $3 #將代換的檔案插入空出的位置
    sed -n -e "$((++end)),\$p" tmp.o >> $3 #取得被取代區塊之後面
    請注意,這個script 沒有檢查 <beginline> 及 <endline> 的大小,讀者自己要小心。

     

     
    5.5 簡單的統計運算

     

    功能 計算某欄的平均值
    用法 avg <column> <filename>
    Script ma1
    
      awk "{sum += \$$1;}
           END {print sum/NR}"  $2
     
     
    

     

    功能 計算某欄的最大(小)值
    用法 max <column> <filename>
    Script ma2
    
    awk "
        BEGIN { MAX = -999999}
        { 
          if ( \$$1 > MAX)
    	 MAX = \$$1 
        }
        END {print MAX}"  $2
     
     
    

     

     
    5.6 英文拼字工具

     

    功能 找一個英文字
    用法 (例)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 等參數。當然,shift -n 可以"移動"n個參數。

     

    功能 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  
    解釋 Script s2 會將STDIN含有數個指定字串的「行」抓出來, 使用者可輕易更改這個script,讓他可以grep 更多的pattern。 下面的 spellcorrect 會用到這個關鍵的 script。

     

    功能 Spelling Corrector
    用法spellcorrect <filename>
    Script s3
      1 spell $1 > 1.o
      2 comm -23 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 -23 將使用者的專有字剔除
    3   將剩下的錯字製造出一個編輯指令檔, 對應每一個錯字,有一行 1,$s/oldword/oldword/ 編輯指令
    4   叫出vi (可用其他編輯器取代) 來讓使用者將該編輯指令檔編輯成一個可以更正錯字的編輯指令檔, 對應每一個錯字,有一行 1,$s/oldword/newword/ 編輯指令
      5   叫出ex 編輯器利用此編輯指令檔將原文裡的錯字改掉
    解釋 這個script 先將輸入的檔案利用spell找出字典沒有的字, 其次將使用者的專有字剔除, 然後將剩下的錯字製造出一個編輯指令檔,再叫出vi 來讓使用者 將該檔案編輯成一個可以更正錯字的編輯指令檔,最後 叫出ex 編輯器利用此編輯指令檔將原文裡的錯字改掉。 當然,讀者可自行將vi 取代為自己喜歡的編輯器。
    在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
    
    這樣的 ex script 在執行第一行之後,已將所有的 systen/systens 改成 system/systems了,因而第二行的執行會找不到 systen, 導致執行失敗,第三行不會被執行,因而被編輯的檔案將不會受到任何更動。 讀者應該在editor 內將編輯指令檔改成下面這樣才行:
    
    1,$s/systen/system/g
    w
    

     

     
    5.7 HTML 相關程式

     

    功能 產生一個色表
    Script h1
    echo "<HTML>"
    echo "<TABLE>"
    for R in 00 88 FF 
    do
       for G in 00 88 FF 
       do
          echo "<TR>"
          for B in 00 33 66 99 CC FF
          do
          echo "<TH bgcolor=#$R$G$B>
          <font size=3 color=BLACK>$R $G $B<br>
          <font size=4 color=#$R$G$B>$R $G $B</TH>"
          done
          echo "</TR>"
       done
    done
    echo "</TABLE>"
    echo "</HTML>"
    
    解釋 本 script 會產生一段 HTML 碼,這段 HTML 碼在瀏覽器上會 顯示一個色表,裡面有各種顏色及其對應的 RGB 碼, 使用者可輕易改寫,增加更多的顏色。
    結果
    00 00 00
    00 00 00
    00 00 33
    00 00 33
    00 00 66
    00 00 66
    00 00 99
    00 00 99
    00 00 CC
    00 00 CC
    00 00 FF
    00 00 FF
    00 88 00
    00 88 00
    00 88 33
    00 88 33
    00 88 66
    00 88 66
    00 88 99
    00 88 99
    00 88 CC
    00 88 CC
    00 88 FF
    00 88 FF
    00 FF 00
    00 FF 00
    00 FF 33
    00 FF 33
    00 FF 66
    00 FF 66
    00 FF 99
    00 FF 99
    00 FF CC
    00 FF CC
    00 FF FF
    00 FF FF
    88 00 00
    88 00 00
    88 00 33
    88 00 33
    88 00 66
    88 00 66
    88 00 99
    88 00 99
    88 00 CC
    88 00 CC
    88 00 FF
    88 00 FF
    88 88 00
    88 88 00
    88 88 33
    88 88 33
    88 88 66
    88 88 66
    88 88 99
    88 88 99
    88 88 CC
    88 88 CC
    88 88 FF
    88 88 FF
    88 FF 00
    88 FF 00
    88 FF 33
    88 FF 33
    88 FF 66
    88 FF 66
    88 FF 99
    88 FF 99
    88 FF CC
    88 FF CC
    88 FF FF
    88 FF FF
    FF 00 00
    FF 00 00
    FF 00 33
    FF 00 33
    FF 00 66
    FF 00 66
    FF 00 99
    FF 00 99
    FF 00 CC
    FF 00 CC
    FF 00 FF
    FF 00 FF
    FF 88 00
    FF 88 00
    FF 88 33
    FF 88 33
    FF 88 66
    FF 88 66
    FF 88 99
    FF 88 99
    FF 88 CC
    FF 88 CC
    FF 88 FF
    FF 88 FF
    FF FF 00
    FF FF 00
    FF FF 33
    FF FF 33
    FF FF 66
    FF FF 66
    FF FF 99
    FF FF 99
    FF FF CC
    FF FF CC
    FF FF FF
    FF FF FF
    這個 Script 裡 R,G,B 的參數如果都改為 00, 33, 66, 99, CC, FF,就可以產生一個展示216安全網頁顏色的 HTML 檔

     

    功能 filtering out words: is, this, a
    Command 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:

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

     

     
    5.X 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