這是一篇適合於沒有任何基礎的初學者學習Cent OS常用命令的博客,努力看看能不能寫成一個系列博客。有時,我們需要的只是一道小小的縫隙,讓我們有個支點去打開一扇厚重的門。
八、文件的操作
前面的touch命令,只是Linux中一條簡單的文件創建命令。文件的操作不但包括創建、刪除等,還包括瀏覽、修改等操作,這些都是學習Linux必學的內容,因爲Linux的配置文件或者是Shell編程、程序設計是經常要用到這些工具的。
Linux提供的文件編輯命令很多也很強大,對於初學者來說,重點要掌握vi、cat、more、less、head、tail、grep這些命令的操作。
(1)vi
CentOS 6.5默認安裝下的vi其實就是vim的別名。通過which查看vi命令可知。
[Bob@firstlinux~]$ which vi
aliasvi='vim'
/usr/bin/vim
因此,在CentOS 6.5中使用命令vi與vim一樣,其實是都是調用vim。
vi與vim的關係可以理解爲:vim是vi的加強版本(初學者先這樣理解吧,不大對就是了)。vim不但兼容vi的指令,且功能更加強大。初學者不用糾結於vi與vim之間有多大區別,先從一些簡單的操作入手,這些操作vi與vim是兼容的。
①使用vi創建文件
使用vi創建文件,可以只輸入命令vi或者輸入vi 文件路徑+文件名。
當只輸入vi時,是打開vi程序,新建一個未命名的文件。
當輸入vi跟上文件路徑+文件名時,可以在指定目錄中創建一個指定文件名的文件,如果文件路徑沒有加,則在當前目錄創建一個指定文件名的文件。
兩種方式的創建其實在磁盤上文件都還不存在,要在後續使用保存命令保存後纔算在磁盤上建立,如果不保存,則沒有。
使用:vi 文件名 的方式,如果文件存在,相當於使用vi打開文件。
先試一試,對vi有個大體上的認識:
輸入vihello.c,進入後再按i,在vi中輸入以下內容:
/*main*/
voidmain()
{
/*define*/
char c1,c2;
c1='a';
c2='b';
c1=c1-32;
c2=c2-32;
/*print*/
printf("%c %c",c1,c2);
}
按Esc鍵,輸入:wq。
注意:在輸入時,代碼行不是使用tab鍵空出,而使用前面使用兩個空格空出(後面查詢時會把這個文件當樣板用)。
上面例子,先使用vihello.c在當前目錄中創建文件hello.c,進入vi編輯器後,按i鍵表示進入編輯模式,輸入內容後按Esc表示退出編輯模式,輸入:wq表示保存並退出vi(其中w代表保存,q代表退出)。
②vi的三種模式
vi有三種模式,分別是:命令模式、編輯模式(也稱插入模式)、末行模式(底行模式)。其實命令模式與末行模式之間差別並不大,在命令模式輸入:就是表示進入末行模式。
③光標的定位
vi一開始運行時是處於命令模式下,在命令模式下定位光標的方法有:
可以使用h(左),j(下),k(上),l(右)或上、下、左、右的方向鍵來移動光標;
可以按shift+g,直接將光標移動到文件最後一行第一個符號位置(前面有空格跳過);
可以按兩次的g,直接將光標移動到文件第一行第一個符號位置(前面有空格跳過);
可以輸入一個非0阿拉伯數字再按兩次g,直接將光標移動阿拉伯數字對應的行第一個符號位置(前面有空格跳過);
可以按0,直接將光標移動到當前行的最前位置(空格也算);
可以輸入$,直接將光標移動到當前行的最後位置(空格也算);
④模式切換
Esc鍵是退出編輯模式進入命令模式和末行模式的按鍵,要從命令模式或末行模式進入編輯模式可選的方式比較多:
按i鍵在當前光標前進入編輯模式;
按shift+i鍵在當前光標行首進入編輯模式;
按a鍵在當前光標後進入編輯模式;
按shift+a鍵在當前光標行行末進入編輯模式;
按o鍵在當前光標行的下面新增一行開始編輯;
按shift+o鍵在當前光標行的上面新增一行開始編輯;
按r鍵再輸入字符會替換當前光標位置的字符繼續編輯;
按shift+r鍵再輸入字符會替換當前光標位置與其後的字符,直到按Esc鍵結束;
對於初學者可以不要記憶太多,記住按i鍵可進入編輯(且爲插入)模式就可以了。
⑤複製、粘貼、刪除、撤消、重做、查找
在文件編輯過程中,複製、粘貼、刪除、撤消、重做、查找可以說是最常用的操作了,在vi中這些操作要在命令模式下完成。
複製常見操作有兩種:按兩次yy,複製光標所在行到緩衝區(緩衝區可以理解成windows中的剪貼板);輸入阿拉伯數字再按兩次yy,複製光標所在行與這行下的阿拉伯數字-1行的內容到緩衝區。
粘貼操作:按p將緩衝區內容粘貼到當前光標所行的下面一行。
刪除常見操作有兩種:按兩次d刪除當前光標所在行;輸入阿拉伯數字再按兩次dd,刪除光標所在行與這行下的阿拉伯數字-1行的內容。
撤消操作:按u
重做操作:按.
查找操作有兩種:輸入/後面接要查找的字符(正向查找);輸入?後面接要查找的字符(反向查找)。如果要繼續就按n鍵,如果退出查找輸入:noh(一條末行模式的命令)。
⑥常見末行模式的命令
命令 | 功能 |
:n1,n2s/w1/w2/g | 將n1到n2行中的w2替換成w1 |
:g/w1/s//w2/g | 將文中全都的w2替換成w1 |
:set nu | 顯示行號 |
:set nonu | 不顯示行號 |
:noh | 關閉查詢 |
:q | 退出文件,如果修改但沒保存要用q!或wq |
:q! | 不保存強制退出 |
:w | 保存文件 |
:wq | 保存強制退出 |
:r 文件名 | 將文件名對應的文件讀取到當前光標下面行 |
:w 文件名 | 將文件另存爲文件名的文件,當前編輯文件沒有變,還是原來的文件,即相當複製一份文件出來另存。 |
:w >>文件名 | 將當前文件添加到指定文件後面 |
⑦多窗口編輯文件
如果一次要打開多個文件,怎麼辦?
例1:一次性打開兩個文件,縱向排列
vi -o 文件1 文件2
例2:一次性打開兩個文件,橫向排列
vi -O 文件1 文件2
即:-o是縱向排列,-O是橫向排列;要打開幾個文件就在後面羅列幾個文件名(中間空格格開)。
如果打開多個文件,怎麼樣判斷當前正在處理的文件,怎麼切換呢?如果要切換可以按住ctrl再按兩次w就可以依次的切換要處理的文件,當前在處理的文件下面的文件名字體是粗體。
例3:在已打開文件後,要再同時打開一個文件
在縱向方向打開 sp 文件名
在橫向方向打開 vsp 文件名
(2)cat查看文件
要查看文件直接使用cat命令後面空格加文件名,如果多個文件,則文件名之間用空格分開。例如:
cathello.c file2
上面命令同時查看hello.c與file2兩個文件,顯示hello.c後面直接跟着file2的內容。如果要顯示行號,加參數-n(不管有多少個文件,行號都是連續編號)。
使用cat瀏覽文件,如果文件內容多的話會滾動,只能看到一屏。所以,對於文件內容比較多的文件查看,這種方式並不便利。如果要分屏,一屏一屏的看,要使用more或less。
(3)more與less命令
more與less命令比cat命令改進的地方是:如果內容超過一屏會以分屏顯示,當按enter鍵時會一行一行顯示出來,按space鍵時,會一屏一屏顯示出來。如果中間不想瀏覽了,直接按q鍵就可以退出。
more命令有進度顯示(查看了多少百分比),less命令沒有進度顯示。
more與less命令在查看上雖然比cat改進了很多,但是有時要查看的只是文件的開頭幾行或最後增加的幾行,這時就要使用命令head或tail。
(4)head或tail命令
①head命令指定顯示一個文件開頭幾行,不加參數,默認顯示是10行,格式:
head -n文件名
-n表示要顯示n行,不加默認10行
②tail命令與head類似,指定顯示一個文件最後幾行,不加參數,默認顯示是10行,格式:
tail-n 文件名
-n表示要顯示n行,不加默認10行。
(5)強大的grep命令
grep全稱globalregular expression print。它的作用是在不打開文件的情況下,根據設定的條件,查找出滿足條件的行並顯示滿足條件的行。
以前面的hello.c文件爲例,進行查找。
例1:查找包含printf的行
[Bob@firstlinux~]$ grep 'printf' hello.c
printf("%c %c",c1,c2);
''內表示要查找的內容。
例2:查找包含/*註釋的行,並顯示出其行號
[Bob@firstlinux~]$ grep -n '/\*' hello.c
1:/*main*/
4: /*define*/
10: /*print*/
''內的*前面要加上\,表示轉義,參數-n表示顯示行號。
例3:查找不包含/*註釋的行
[Bob@firstlinux~]$ grep -v '/\*' hello.c
voidmain()
{
char c1,c2;
c1='d';
c2='b';
c1=c1-32;
c2=c2-32;
printf("%c %c",c1,c2);
}
加上參數-v表示查找不包括表示式中內容的行。
例4:計算包含字符printf的行數
[Bob@firstlinux~]$ grep -c 'print' hello.c
2
查詢結果是個數值,加參數-c是統計符合查詢的條件的行數。
例5:查詢當前目錄下hello.c file2 file3三個文件中包含printf的行,並顯示行號
[Bob@firstlinux~]$ grep -n 'printf' hello.c file2 file3
結果略...
如果對多個文件進行查詢,將文件依次羅列並以空格格開。
例6:對當前目錄下文件名包含e字符的所有文件查詢包含printf的行,並顯示行號
[Bob@firstlinux~]$ grep -n 'printf' *e*
結果略...
在查詢範圍中,如果文件名不確定,可以使用通配符。通配符中最常用的是?和*,?代表一個字符,*代表任意個字符。
例7:查詢hello.c文件中前三個字符不是空格、空格、c組成的行,並顯示行號
[Bob@firstlinux~]$ grep -nv "^\ \ c" hello.c
1:/*main*/
2:voidmain()
3:{
4: /*define*/
10: /*print*/
11: printf("%c %c",c1,c2);
12:}
參數-n與-v合併成-nv,^表示行的開始,前兩個空格使用轉義字符\+空格來表示空格字符。
例8:在查詢前先在hello.c第七行下面添加一行,內容爲Case。不區分大小寫查詢hello.c文件中前三個字符是空格、空格、c組成的行,並顯示行號。
[Bob@firstlinux~]$ grep -in '^\ \ c' hello.c
5: char c1,c2;
6: c1='d';
7: c2='b';
8: Case;
9: c1=c1-32;
10: c2=c2-32;
不區分查詢關鍵字的大小寫,要加參數-i。上面參數-i與-n合併寫成-in。
例9:查詢hello.c文件中最後兩個字符爲';的行,並顯示行號
[Bob@firstlinux~]$ grep -n "';$" hello.c
6: c1='d';
7: c2='b';
如果查詢中的內容包含',要查詢的字符串可以改成使用""包含,反之也一樣。如果要查詢的是一行的最後幾個符號在查詢字符串後面加$。$表示行的結束。
例10:查詢行中包含以m開始再間隔兩個字符後爲n的行,並顯示行號
[Bob@firstlinux~]$ grep -n 'm..n' hello.c
1:/*main*/
2:voidmain()
.表示必須有一個任意字符。
例11:查詢包含有p或v兩個字符中的一個的行,並顯示行號
[Bob@firstlinux~]$ grep -n '[pv]' hello.c
2:voidmain()
11: /*print*/
12: printf("%c %c",c1,c2);
其中[pv]表示行中要包含有p或v兩個字符中的一個。
例12:查詢包含有從h至j之間(含h與j)字符的行,並顯示行號
[Bob@firstlinux~]$ grep -n '[h-j]' hello.c
1:/*main*/
2:voidmain()
4: /*define*/
5: char c1,c2;
11: /*print*/
12: printf("%c %c",c1,c2);
例13:查詢前先進行如下操作
[Bob@firstlinux~]$ mkdir testone/subtest -p
[Bob@firstlinux~]$ cp hello.c testone/a.c
[Bob@firstlinux~]$ cp hello.c testone/subtest/b.c
如果要查詢出testone目錄(包含子目錄)下所有包含有print字符的文件,則:
[Bob@firstlinux~]$ grep -rl "print" testone
testone/a.c
testone/subtest/b.c
其中r參數表示遞歸,l參數表示只顯示文件名,如果不加l參數,則查詢結果爲:
[Bob@firstlinux~]$ grep -r "print" testone
testone/a.c: /*print*/
testone/a.c: printf("%c %c",c1,c2);
testone/subtest/b.c: /*print*/
testone/subtest/b.c: printf("%c %c",c1,c2);
例14:如果要查詢包含main或print兩個單詞的行,並顯示行號,則
[Bob@firstlinux~]$ grep -n -e "main" -e "print" hello.c
1:/*main*/
2:voidmain()
11: /*print*/
12: printf("%c %c",c1,c2);
上面的查詢,如果要查詢的單詞更多,可以將單詞做成一個文件,每行一個,進行查詢。比如,先創建要查詢單詞的文件vi pattern,在文件中輸入以下三行
main
case
下來查詢hello.c文件中包含pattern文件中三行單詞的行,並顯示出行號,操作如下:
[Bob@firstlinux~]$ grep -n -f pattern hello.c
1:/*main*/
2:voidmain()
11: /*print*/
12: printf("%c %c",c1,c2);
[Bob@firstlinux~]$ grep -in -f pattern hello.c
1:/*main*/
2:voidmain()
8: Case;
11: /*print*/
12: printf("%c %c",c1,c2);
兩條命令都使用-f這個參數後面加要查詢單詞存放的文件名,以這文件內每行的單詞爲查詢字符串進行查詢。
第一條命令少個參數i,所以少了第8行。(加i參數不區分大小寫)。
(第三篇 完 待續...)