UNIX 文字工具: 抽出任一列

如果我們想要印出 forty.txt 裡面的第 7 列,可以說

head -7 forty.txt | tail -1
這個作法的缺失是,如果 forty.txt 根本不足 7 列, 就會印出它的最後一列,但是您不知道。 除非另外用 wc -l 去檢查 forty.txt 一共有幾列。

另一個想法是用 cat -n 得知列號,再搜尋列號是 7 的那一列:

cat -n forty.txt | grep 7
這樣做有幾個明顯的缺點,只要看看結果就知道了:
     7  seven little
    17  seven little
    27       7  seven little
    37      17  seven little
如果我們可以要 grep 搜尋前面有一個空格、後面有一個跳格的 7,那就應該好多了。 如果 grep 的搜尋字串包括空格或跳格, 就應該把整個搜尋字串放在一對 ' (single-quote) 符號裡面。 指令應該是
cat -n forty.txt | grep ' 7	'
讀者從網頁中看不出來,7 的前面是一個空格,而後面是一個跳格。

這樣做可能有一個問題,那就是如果您使用的是 T-C shell 文字介面, 則這個介面將跳格符號保留做補足檔案名 (filename completion) 之用。所以當您按下 [Tab] 按鍵的時候,會出現奇怪的結果 (如果目前資料夾中有一個檔案的名字從 7 符號開始的話), 或是出現錯誤訊息 (如果沒有一個檔案的名字從 7 符號開始的話)。 要避開這個困難的最簡單方法,就是臨時進入一個不把跳格當做特殊符號的文字介面, 譬如 Bourne shell。 您可以下指令 sh 進入 Bourne shell,完成工作後再 exit 回到原來的介面。 例如

sh
cat -n forty.txt | grep ' 7	'
exit
就會得到結果
     7  seven little
    27       7  seven little
還是有問題。很不幸的,forty.txt 檔案的內容本身,就有 [Space]7[Tab] 的字串出現。 而且它在第 27 列,不應該被找到才對。

但是我們還可以指揮 grep 做更精確的搜尋。 在搜尋字串裡面,可以用一個描述指令來指稱一列的開始:^ (hat) 符號。 我們要搜尋從一列的頭開始,連續五個空格,之後跟一個 7,之後再跟一個跳格。 也就是

sh
cat -n forty.txt | grep '^     7	'
exit
讀者必須注意,7 的後面是一個跳格。 就會得到結果
     7  seven little
現在差不多對了。但是 forty.txt 的第七列只有 seven little,不該把列號也印出來。 只要再用 sed 將列號 (包括那個跳格) 刪除掉即可。 如果要將結果存檔,也可以在 Bourne shell 裡面做。整個指令是
sh
cat -n forty.txt | grep '^     7	' | sed 's/^     7	//' > seventh.txt
exit
回到 T-C shell 裡面之後,再 cat seventh.txt 看看,結果應該是正確的。 注意 sed 的置換指令,NEW_STRING 的部分是個空集合,那就是刪除 OLD_STRING 的意思。 注意那兩個 7 的後面都是一個跳格。

習題

[ 前一節 ]‧[ 後一節 ]‧[ 回目錄 ]



注意:此處所有文件均為原著,個別的版權宣告日後會一一公布, 整體版面設計亦尚未完成。但仍請勿抄襲文字與圖片,以免觸犯著作權法。

Created: Nov 19, 2000
Last Revised: Nov 19, 2000
© Copyright 2000 Wei-Chang Shann 單維彰

shann@math.ncu.edu.tw