天天看點

外部過濾器, 程式和指令

基本指令

ls

: "列出"檔案的基本指令. 但是往往就是因為這個指令太簡單, 是以我們總是低估它. 比如, 使用-r選項, 遞歸選項,

ls将會以目錄樹的形式列出所有檔案. 另一個很有用的選項-s, 将會按照檔案尺寸列出所有檔案, -t, 将會按照修改時間來列出檔案,

-i選項會顯示檔案的inode。

cat, tac

: cat, 是單詞concatenate的縮寫, 把檔案的内容輸出到stdout. 當與重定向操作符(>或>>),

一般都是用來将多個檔案連接配接起來.

cat指令的-n選項是為了在目标檔案中的所有行前邊插入行号.

-b也是用來加行号的, 但是不對空行進行編号. -v選項可以使用^标記法來echo出不可列印字元. -s選項可以把多個空行壓縮成一個空行.  

     在一個管道中, 有一種把stdin重定向到一個檔案中更有效的方法,

這種方法比使用cat檔案的方法更高效.

cat filename | tr a-z a-z

            tr a-z a-z < filename # 效果相同,

但是處理更少,并且連管道都省掉了

tac指令, 就是cat指令的反轉,

這個指令将會從檔案結尾部分列出檔案的内容.反向cat。

rev

: 把每一行中的内容反轉, 并且輸出到stdout上. 這個指令與tac指令的效果是不同的, 因為它并不反轉行序,

而是把每行的内容反轉.

cp

: 這是檔案拷貝指令. cp file1 file2把檔案file1拷貝到file2, 如果file2存在的話,

那麼file2将被覆寫。 特别有用的選項就是-a選項, 這是歸檔标志(目的是為了copy一個完整的目錄樹), -u是更新選項,

-r和-r選項是遞歸标志.

cp -u source_dir/*

dest_dir  #

把源目錄"同步"到目标目錄上,  也就是拷貝所有更新的檔案和之前不存在的檔案.

mv

: 這是檔案移動指令. 它等價于cp和rm指令的組合. 它可以把多個檔案移動到目錄中,甚 至将目錄重命名.當使用非互動腳本時,

可以使用mv的-f(強制)選項來避免使用者的輸入.當一個目錄被移動到一個已存在的目錄時, 那麼它将成為目标目錄的子目錄.

rm

: 删除(清除)一個或多個檔案. -f選項将強制删除檔案, 即使這個檔案是隻讀的. 并且可以用來避免使用者輸入(在非互動腳本中使用).

 當使用遞歸參數-r時, 這個指令将會删除整個目錄樹. 如果不慎的使用rm -rf *的話, 那整個目錄樹就真的完了.

rm将無法删除以破折号開頭的檔案.解決這個問題的一個方法就是在要删除的檔案的前邊加上./。另一種解決的方法是在檔案名前邊加上"

-- ".  rm ./-badname 。 rm -- -badname

rmdir

: 删除目錄. 但是隻有這個目錄中沒有檔案的時候 -- 當然會包含"不可見的"點檔案  -- 這個指令才會成功.

mkdir

: 生成目錄, 建立一個空目錄. 比如, mkdir -p

project/programs/december将會建立指定的目錄,即使project目錄和programs目錄都不存在. -p選項将會自動産生必要的父目錄,

這樣也就同時建立了多個目錄.

chmod

: 修改一個現存檔案的屬性。 chmod +x filename  ,  chmod 644

filename

ln

: 建立檔案連結, 前提是這個檔案是存在的. "連結"就是一個檔案的引用, 也就是這個檔案的另一個名字. ln指令允許對同一個檔案引用多個連結,

并且是避免混淆的一個很好的方法。 ln對于檔案來說隻不過是建立了一個引用, 一個指針而已, 因為建立出來的連接配接檔案隻有幾個位元組.

絕大多數使用ln指令時, 使用的是-s選項,

可以稱為符号連結, 或"軟"連結. 使用-s标志的一個優點是它可以穿越檔案系統來連結目錄. 關于使用這個指令的文法還是有點小技巧的. 比如: ln

-s oldfile newfile将對之前存在的oldfile産生一個新的連接配接, newfile.如果之前newfile已經存在的話,

将會産生一個錯誤資訊.

不論是那種類型的連結, 都提供了一種雙向引用的手段 --

也就是說, 不管你用檔案的哪個名字對檔案内容進行修改, 你修改的效果都即會影響到原始名字的檔案, 也會影響到連結名字的檔案. 當你工作在更高層次的時候,

才會發生軟硬連結的不同. 硬連結的優點是, 原始檔案與連結檔案之間是互相獨立的 -- 如果你删除或者重命名舊檔案, 那麼這種操作将不會影響硬連結的檔案,

硬連結的檔案講還是原來檔案的内容. 然而如果你使用軟連結的話, 當你把舊檔案删除或重命名後, 軟連結将再也找不到原來檔案的内容了.

而軟連結的優點是它可以跨越檔案系統(因為它隻不過是檔案名的一個引用, 而并不是真正的資料). 與硬連結的另一個不同是,

一個符号連結可以指向一個目錄.

man, info

: 這兩個指令用來檢視系統指令或安裝工具的手冊和資訊. 當兩者都可用時, info頁一般會比man頁包含更多的細節描述.

複雜指令

find

-exec command

\; 在每一個find比對到的檔案執行command指令.

指令序列以;結束(";"是轉義符以保證shll傳遞到find指令中的字元不會被解釋為其他的特殊字元).如果command中包含{},

那麼find指令将會用所有比對檔案的路徑名來替換"{}".      

 find指令的-exec選項不應該與shell中的内建指令exec相混淆.

find ~/ -name ‘core*‘ -exec

rm {} \;  # 從使用者的 home 目錄中删除所有的 core dump檔案.

find /home/bozo/projects

-mtime 1  # 列出最後一天被修改的  # mtime = 目标檔案最後修改的時間  # ctime

= 修改後的最後狀态(通過‘chmod‘或其他方法)  # atime = 最後通路時間

find "$dir" -type f -atime +5

-exec rm {} \; 删除至少5天内沒被通路過的  "/home/bozo/junk_files"

中的所有檔案.

expr

: 通用求值表達式: 通過給定的操作(參數必須以空格分開)連接配接參數, 并對參數求值. 可以使算術操作, 比較操作,

字元串操作或者是邏輯操作.

expr 5 \* 3  #傳回15,

在算術表達式expr中使用乘法操作時, 乘法符号必須被轉義.

y=`expr $y + 1` 增加變量的值,

與let y=y+1和y=$(($y+1))的效果相同. 這是使用算術表達式的一個例子.

z=`expr substr $string

$position $length` 在位置$position上提取$length長度的子串.

:操作可以替換match指令. 比如, b=`expr

$a : [0-9]*`與b=`expr match $a [0-9]*`完全等價.

時間/日期

指令

date

: 直接調用date指令就會把日期和時間輸出到 stdout上.

這個指令有趣的地方在于它的格式化和分析選項上. 需要在調用格式的前邊加上一個‘+‘号.

date +%j

# %j用來給出今天是本年度的第幾天.

%s将産生從"unix

元年"到現在為止的秒數。suffix=$(date +%s) , filename=$prefix.$suffix  #

這是一種非常好的産生"唯一"臨時檔案的辦法,甚至比使用$$都強.

touch

: 這是一個用來更新檔案被通路或修改的時間的工具, 這個時間可以是目前系統的時間,也可以是指定的時間, 這個指令也用來産生一個新檔案. 指令touch

zzz将産生一個zzz為名字的0位元組長度檔案, 當然前提是zzz檔案不存在. 為了存儲時間資訊, 就需要一個時間戳為空的檔案,

比如當你想跟蹤一個工程的修改時間的時候, 這就非常有用了.

at : at指令是一個作業控制指令,

用來在指定時間點上執行指定的指令集合. 它有點像cron指令, 然而,

at指令主要還是用來執行那種一次性執行的指令集合. 你可以使用-f選項或者使用(<)重定向操作符, 來讓at指令從一個檔案中讀取指令集合.

這個檔案其實就一個可執行的的腳本, 雖然它是一個不可互動的腳本。 at 2:30 am friday <

at-jobs.list

cal

: 從stdout中輸出一個格式比較整齊的月曆. 既可以指定目前年度, 也可以指定過去或将來的某個年度.

sleep

:這個指令與一個等待循環的效果一樣. 你可以指定需要暫停的秒數, 這段時間将什麼都不幹。 sleep 3 # 暫停3秒。sleep預設是以秒為機關,

但是你也可以指定分鐘, 小時, 或者天數為機關. sleep 3 h # 暫停3小時!    

 如果你想每隔一段時間來運作一個指令的話, 那麼watch指令将比sleep指令好得多.

文本處理指令

sort

: 檔案排序, 通常用在管道中當過濾器來使用. 這個指令可以依據指定的關鍵字或指定的字元位置, 對檔案行進行排序. 使用-m選項,

它将會合并預排序的輸入檔案. 想了解這個指令的全部參數請參考這個指令的info頁.

tsort

: 拓撲排序, 讀取以空格分隔的有序對, 并且依靠輸入模式進行排序.

uniq

:這個過濾器将會删除一個已排序檔案中的重複行. 這個指令經常出現在sort指令的管道後邊. 

cat list-1 list-2 list-3 |

sort | uniq > final.list #

将3個檔案連接配接起來, 将它們排序, 删除其中重複的行,最後将結果重定向到一個檔案中.

-c用來統計每行出現的次數,

并把次數作為字首放到輸出行的前面.

sort inputfile | uniq -c |

sort -nr 指令先對inputfile檔案進行排序, 然後統計每行出現的次數(sort指令的-nr選項會産生一個數字的反轉排序).

這種指令模闆一般都用來分析log檔案或者用來分析字典清單, 或者用在那些需要檢查文本詞彙結構的地方.

sed -e ‘s/\.//g‘ -e ‘s/\,//g‘

-e ‘s/ /\

/g‘ "$1" |

tr ‘a-z‘ ‘a-z‘ | sort | uniq -c | sort -nr   #

過濾掉句号和逗号, 并且把單詞間的空格轉化為換行, 然後轉化為小寫, 最後統計單詞出現的頻率并按頻率排序.

expand,

unexpand : expand指令将會把每個tab轉化為一個空格.

這個指令經常用在管道中.unexpand指令将會把每個空格轉化為一個tab. 效果與expand指令相反.

cut : 一個從檔案中提取特定域的工具.

這個指令與awk中使用的print $n指令很相似, 但是更受限. 在腳本中使用cut指令會比使用awk指令來得容易一些.

最重要的選項就是-d(字段定界符)和-f(域分隔符)選項.

cut -d ‘ ‘ -f1,2

/etc/mtab

paste : 将多個檔案,

以每個檔案一列的形式合并到一個檔案中, 合并後檔案中的每一列就是原來的一個檔案.與cut結合使用, 經常用于建立系統log檔案.

join : 這個指令與paste指令屬于同類指令.

但是它能夠完成某些特殊的目地. 這個強力工具能夠以一種特殊的形式來合并兩個檔案,

這種特殊的形式本質上就是一個關聯資料庫的簡單版本.join指令隻能夠操作兩個檔案. 它可以将那些具有特定标記域(通常是一個數字标簽)的行合并起來,

并且将結果輸出到stdout. 被加入的檔案應該事先根據标記域進行排序以便于能夠正确的比對. 

head : 把檔案的頭部内容列印到stdout上(預設為10行,

可以自己修改). 這個指令有一些比較有趣的選項.

tail : 将一個檔案結尾部分的内容輸出到stdout中(預設為10行).

通常用來跟蹤一個系統logfile的修改情況,如果使用-f選項的話, 這個指令将會繼續顯示添加到檔案中的行.

為了列出一個文本檔案中的指定行的内容,

可以将head指令的輸出通過管道傳遞到tail -1中. 比如head -8 database.txt | tail

-1将會列出database.txt檔案第8行的内容.

var=$(head -$m $filename |

tail -$n)  # filename = 檔案名 # m = 從檔案開頭到塊結尾的行數 # n =

想儲存到變量中的指定行數(從塊結尾開始截斷)

grep : 使用正規表達式的一個多用途文本搜尋工具.

這個指令本來是ed行編輯器中的一個指令/過濾器: g/re/p -- global - regular expression -

print.

grep pattern

[file...] 在檔案中搜尋所有pattern出現的位置, pattern既可以是要搜尋的字元串, 也可以是一個正規表達式.

grep ‘[rst]ystem.$‘

osinfo.txt #linux operating system.  #如果沒有指定檔案參數,

grep通常用在管道中對stdout進行過濾.

-i 選項在搜尋時忽略大小寫. -w

選項用來比對整個單詞. -l 選項僅列出符合比對的檔案, 而不列出比對行. -r (遞歸) 選項不僅在目前工作目錄下搜尋比對, 而且搜尋子目錄. -n

選項列出所有比對行, 并顯示行号. -v (或者--invert-match)選項将會顯示所有不比對的行.  -c (--count)

選項将隻會顯示比對到的行數的總數,而不會列出具體的比對.

grep -n linux osinfo.txt #6:

linux operating system.

如果存在一個成功的比對,

那麼grep指令将會傳回0作為退出狀态碼, 這樣就可以将grep指令的結果放在腳本的條件測試中來使用, 尤其和-q(禁止輸出)選項組合時特别有用. grep

-q "$word" "$filename" # "-q"選項将使得什麼都不輸出到stdout上.

egrep -

擴充的grep - 這個指令與grep -e等價. 這個指令用起來有些不同, 由于使用正規表達式的擴充集合, 将會使得搜尋更具靈活性.

它也允許邏輯|(或)操作. egrep ‘matches|matches‘ file.txt

fgrep - 快速的grep - 這個指令與grep

-f等價. 這是一種按照字元串字面意思進行的搜尋(即不允許使用正規表達式), 這樣有時候會使搜尋變得容易一些.

look :look指令與grep指令很相似,

但是這個指令隻能做"字典查詢", 也就是它所搜尋的檔案必須是已經排過序的單詞清單. 預設情況下, 如果沒有指定搜尋哪個檔案,

look指令就預設搜尋/usr/dict/words(譯者:感覺好像應該是/usr/share/dict/words),

當然也可以指定其他目錄下的檔案進行搜尋.

sed, awk

:這個兩個指令都是獨立的腳本語言, 尤其适合分析文本檔案和指令輸出. 既可以單獨使用, 也可以結合管道和在shell腳本中使用.

sed : 非互動式的"流編輯器", 在批處理模式下,

允許使用多個ex指令. 你會發現它在shell腳本中非常有用.

awk : 可程式設計的檔案提取器和檔案格式化工具,

在結構化的文本檔案中, 處理或提取特定域(特定列)具有非常好的表現. 它的文法與c語言很類似.

wc : wc可以統計檔案或i/o流中的"單詞數量": 

wc -w 統計單詞數量. wc -l 統計行數量. wc

-c 統計位元組數量.wc -m 統計字元數量.wc -l 給出檔案中最長行的長度.

ls *.txt | wc

-l #因為列出的檔案名都是以換行符區分的, 是以使用-l來統計.

tr

: 字元轉換過濾器. 必須使用引用或中括号, 這樣做才是合理的. 引用可以阻止shell重新解釋出現在tr指令序列中的特殊字元.

中括号應該被引用起來防止被shell擴充.

無論tr "a-z" "*"

<filename還是tr a-z \* <filename都可以将filename中的大寫字元修改為星号(寫到stdout).

但是在某些系統上可能就不能正常工作了, 而tr a-z ‘[**]‘在任何系統上都可以正常工作.

-d選項删除指定範圍的字元. echo

"abcdef" | tr -d b-d # aef .  tr -d 0-9 <filename #

删除"filename"中所有的數字.

--squeeze-repeats

(或-s)選項用來在重複字元序列中除去除第一個字元以外的所有字元. 這個選項在删除多餘空白的時候非常有用.  echo "xxxxx" | tr

--squeeze-repeats ‘x‘  # x

-c"complement"選項将會反轉比對的字元集.

通過這個選項, tr将隻會對那些不比對的字元起作用. echo "acfdeb123" | tr -c b-d +

# +c+d+b++++

tr a-z a-z <"$1" , tr

‘[:lower:]‘ ‘[:upper:]‘ <"$1" 全部轉換為大寫.

tr ‘a-za-z‘ ‘n-za-mn-za-m‘ #

"a"變為"n", "b"變為"o", 等等.

fold : 将輸入按照指定寬度進行折行. 這裡有一個非常有用的選項-s,

這個選項可以使用空格進行斷行(譯者:事實上隻有外文才需要使用空格斷行, 中文是不需要的)

fmt : 一個簡單的檔案格式器, 通常用在管道中, 将一個比較長的文本行輸出進行"折行". fmt

-w $width

col : 這個指令用來濾除标準輸入的反向換行符号. 這個工具還可以将空白用等價的tab來替換.

col工具最主要的應用還是從特定的文本處理工具中過濾輸出, 比如groff和tbl.

column : 列格式化工具. 通過在合适的位置插入tab,

這個過濾工具會将列類型的文本轉化為"易于列印"的表格式進行輸出.

ls -l | sed 1d) | column -t # 管道中的"sed 1d"删除輸出的第一行,

"column"中的-t選項用來轉化為易于列印的表形式.

colrm : 列删除過濾器. 這個工具将會從檔案中删除指定的列(列中的字元串)并且寫到檔案中,

如果指定的列不存在, 那麼就回到stdout. colrm 2 4 <filename将會删除filename檔案中每行的第2到第4列之間的所有字元.

  如果這個檔案包含tab和不可列印字元, 那将會引起不可預期的行為. 在這種情況下,

應該通過管道的手段使用expand和unexpand來預處理colrm.

nl : 計算行号過濾器. nl filename将會把filename檔案的所有内容都輸出到stdout上,

但是會在每個非空行的前面加上連續的行号. 如果沒有filename參數, 那麼就操作stdin.nl指令的輸出與cat -n非常相似, 然而,

預設情況下nl不會列出空行.