基本指令
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不會列出空行.