Linux 學習 第五章 使用文字檔案

📢 本文由 gemini-3-flash-preview 翻譯

第五章 使用文字檔案

Linux 的大多數設定透過編輯純文字檔完成。無論是修改 /etc 目錄的檔案設定在地服務,還是編輯 Ansible 目錄檔案設定主機的集合,純文字檔仍然在這些任務中普遍使用。

5.1 使用 vim 和 vi 編輯檔案

vim 是 vi 的改良版本,兩者使用方式差不多,但 vim 會有引導和語法突顯(程式碼高亮)等功能,建議使用 vim。

事實上,在部分 Linux 發行版中,vi 是使用別名 vim 來執行的,即輸入 alias vi 輸出為 alias vi = 'vim' ,但 root 使用者一般不設定別名。

不過在 Linux 還有其他文字編輯器,例如 nano、gedit、jed、joe、kate、kedit、mcedit、nedit 等,其中純文字的有 jed 和 joe。

5.1.1 開始使用 vi

vi 有三個模式,主要兩種為 指令模式輸入模式 ,還有 ex 模式。預設進入檔案為指令模式 (使用 vi file 指令進入後)。

指令模式意味著在更改文字前需要先輸入一條指令 (一兩個字母,有時還需要選用的數字參數) ,告訴 vi 您想做什麼。

注意:指令的大小寫敏感。

  1. 新增文字

如果要進入 輸入模式 ,可以輸入一個 輸入 指令字母。

指令描述
a新增指令。在游標右側輸入文字
A在行尾新增。從目前行末尾開始輸入文字
i插入指令。在游標左側輸入文字
I在行首插入。從目前行開頭開始輸入文字
o在下方開啟。在目前行之下開啟一個新行,並進入插入模式
O在上方開啟。在目前行之上插入一個新行,並進入插入模式

進入插入模式後,在螢幕底部會出現 --INSERT--

完成文字輸入後,按 Esc 鍵返回指令模式 (有時需要按兩次 (反正按 Esc 就對了)。

  1. 在文字中移動

僅移動一個字元使用以下按鍵:

按鍵描述
方向鍵上下左右
h, j, k, l左,下,上,右
Backspace, Space左,右

移動多個字元的指令:

指令描述
w將游標移動到下一個單字的開頭 (用空白、Tab 或標點符號分隔)
W將游標移動到下一個單字的開頭 (用空白或 Tab 分隔)
b將游標移動到前一個單字的開頭 (用空白、Tab 或標點符號分隔)
B將游標移動到前一個單字的開頭 (用空白或 Tab 分隔)
0 (零)將游標移到目前行的開頭
$將游標移到目前行的末尾
H將游標移到螢幕左上角 (螢幕上第一行)
M將游標移到螢幕中間行的第一個字元
L將游標移到螢幕的左下角 (螢幕上的最後一行)
  1. 刪除、複製和更改文字

這些指令可以配合移動鍵 (方向鍵、PgUp、PgDn、字母和特殊鍵) 和數字來確切指出刪除、複製或更改什麼。

指令描述
x刪除游標下的字元
X直接刪除游標之前的字元
d刪除一些文字
c更改一些文字
y複製一些文字

上表每個指令後的 <?> 代表了可使用移動指令的位置,例如:

  • dw — 刪除目前游標之後的一個單字
  • db — 刪除目前游標之前的一個單字
  • dd — 刪除整個目前行
  • c$ — 更改目前字元開始到目前行末尾的字元並進入輸入模式 (事實上就是刪除後輸入)
  • c0 — 更改從前一字元開始到目前行開頭的字元並進入輸入模式 (事實上就是刪除後輸入)
  • cl — 刪除目前字元並進入輸入模式
  • cc — 刪除目前行並進入輸入模式
  • yy — 將目前行複製到緩衝區
  • y) — 將游標右邊的句子複製到緩衝區
  • y} — 將游標右邊的段落複製到緩衝區

也可以使用數字對上述指令進行修改,例如:

  • 3dd — 從目前行開始,刪除 3 行
  • 3dw — 刪除接下來的 3 個單字
  • 5cl — 更改接下來 5 個字元 (也就是刪除後進入輸入模式)
  • 12j — 向下移動 12 行
  • 5cw — 刪除接下來 5 個單字並進入輸入模式
  • 4y) — 複製接下來的 4 個句子
  1. 貼上 (放置) 文字

將最新儲存到緩衝區的文字放到檔案中。

指令描述
P放到游標左邊,若為一行,則放到上一行
p放到游標右邊,若為一行,則放到下一行
  1. 重複指令

在刪除、更改或貼上文字後,透過 . 以重複行為。例如替換文字 Joe 為 Jim (cw) 後查找下一處按 . 以重複更改。

  1. 退出 vi

在指令模式下直接使用 ZZ 儲存後退出,也可按 : 進入 ex 模式。

指令描述
:w儲存目前檔案,不退出
:wq儲存並退出,與 ZZ 相同
:q退出,但僅在未更改時生效
:q!強制退出,不儲存更改
  1. 其他指令
  • u — 復原更改
  • Ctrl+R — 重做 (Redo) ,也就是復原先前的復原操作
  • :!command – 在 :! 後跟一個 shell 指令,可直接執行,例如 :!date 查看目前日期。甚至可以透過 :!bash 以啟動一個新 shell,但建議進入前先儲存,以防忘記返回 vi
  • Ctrl+g — 顯示正在編輯的檔名,底部還有目前所在行、檔案總行數、內容百分比以及游標所在列號

5.1.2 在檔案中跳轉

如果檔案較長,用此方法移動更好:

指令描述
Ctrl+f向前翻頁,一次一頁
Ctrl+b向後翻頁,一次一頁
Ctrl+d向前翻半頁
Ctrl+u向後翻半頁
G轉到檔案最後一行
nG轉到檔案第 n 行 (用數字替換 n)

5.1.3 搜尋文字

透過 /? 向前或向後搜尋文字,還可以使用元字元,例如:

  • /hello* — 向前搜尋 hello 開頭的行
  • ?[pP]rint — 向後搜尋單字 print 或 Print

在輸入搜尋後透過 nN 可以在相同或相反方向繼續搜尋。

5.1.4 使用 ex 模式

vi 編輯器最初基於 ex 編輯器,因此無法在全螢幕模式下工作,但可以在 ex 模式下使用指令找到並更改一行或多行的文字,例如:

在指令模式下使用 : 進入 ex 模式:

  • :g/Local — 搜尋單字 Local,並列印相關行,如果輸出結果滿屏將發送到 more 指令
  • :s/Local/Remote — 將目前行首次出現的單字 Local 替換為 Remote
  • :g/Local/s//Remote — 檔案每一行首次出現的 Local 替換為 Remote
  • :g/Local/s//Remote/g — 檔案所有 Local 替換為 Remote
  • :g/Local/s//Remote/gp — 檔案所有 Local 替換為 Remote,並列印每一行

5.1.5 了解更多

使用 vimtutor 將在 vim 編輯器中開啟一個教學課程。

5.2 查找檔案

為幫助找到系統中的檔案,可使用一些指令:

  • locate — 根據名稱查找檔案
  • find — 根據不同的屬性查找檔案
  • grep — 在文字檔案內部搜尋包含所搜尋文字的行

5.2.1 使用 locate 指令根據名稱查找檔案

大多數 Linux 系統每天會執行一次 updatedb 指令,收集 Linux 系統中的檔名並存入資料庫,使用 locate 指令可從該資料庫中搜尋檔案位置。可透過 sudo updatedb 指令更新資料庫。僅可透過 locate 指令查看允許使用者存取的檔案。

locate [str] ,或者使用 locate -i [str] 以忽略大小寫。例如搜尋包含 yexca 的目錄並忽略 yexca 的大小寫:locate -i yexca

註:並不是所有的檔案都在資料庫中,/etc/updated.conf 檔案內容限制了被收集的檔案。

5.2.2 使用 find 指令搜尋檔案

find 指令是在檔案系統中搜尋檔案的最佳指令,可以基於不同屬性 (元資料) 查找,並且可以在找到檔案後進行處理。

註:檔案元資料包括擁有者、群組、時間戳記、檔案大小、權限以及儲存在檔案 inode 中的其他資訊。

find 與 locate 的區別

使用 find 查找將搜尋整個檔案系統,所以速度會比 locate 慢許多,但可以即時查看系統中的檔案 (對於 locate 指令,如果檔案太新未收錄到資料庫將無法被找到)。當然,使用 find 時要設定搜尋起始點以限制搜尋範圍,從而提高速度。

find 指令有一個特殊的選項 -ls ,可以列出搜尋到檔案的詳細資訊,類似 ls -l 指令的輸出。

註:對於一般使用者搜尋檔案因權限問題會有許多錯誤,可將錯誤輸出定向到 /dev/null 以忽略,即在指令末尾添加 2>/dev/null

  1. 根據檔名查找檔案

使用 -name-iname (忽略大小寫) 以輸入想要搜尋的檔名,也可使用萬用字元 (* 和 ?),例如:

1
find /etc -iname '*passwd*'

在 /etc 目錄下搜尋包含 passwd 單字並忽略大小寫的檔案 (如不指定目錄 (/etc) 將搜尋目前資料夾)。

可使用 -type 選項以指定輸出僅檔案 (-type f) 或僅目錄 (-type d)。

  1. 根據檔案大小查找檔案

透過 -size 選項和以 +- 開頭的數字查找相應範圍,例如 find /etc -size +10M 查找 /etc 目錄下大於 10MB 的檔案。

1
find /bigdata -size +500M -size -5G -exec du -sh {} \

查找 /bigdata 目錄下 500MB ~ 5GB 之間的檔案,並針對每個檔案執行 du 指令以查看檔案大小。

  1. 根據使用者查找檔案

透過 -user-group 以針對特定使用者或群組查找,還可使用 -not-or

1
find /home \( -user yexca -or -user lemon \) -ls

查找 /home 目錄下 yexca 和 lemon 所擁有的檔案。

  1. 根據權限查找檔案

使用 -perm 選項,根據數字或字母找到檔案。如果數字前使用 - ,則三位都要匹配;如果使用 + ,任一數字匹配即可;若不加符號,那麼所有數字必須完整、精確匹配。

如果 find -perm /002 則將找到對 “其他人” 啟用了寫入權限的檔案,而不用管其他權限位元如何設定。

  1. 根據日期和時間查找檔案

time 選項 (-atime、-ctime 和 -mtime) 能基於自檔案被存取、更改或者檔案的元資料被更改以來所經歷的天數進行搜尋。而 min 選項 (-amin、-cmin 和 -mmin) 則是基於所經歷的分鐘數。

在上述兩個選項的參數前加 - 表示從目前時間到所查詢的時間單位前的時間,+ 表示所查詢時間單位之前以及更久的時間,如果省略,則完全匹配。

  • 查看 10 分鐘內被更改的內容:
1
find /etc -mmin -10
  • 查看三天內權限更改:
1
find /bin /usr/bin -ctime -3
  • 查看 300 多天未被存取的檔案:
1
find /var/www -atime +300
  1. 在查找檔案時使用 ’not’ 和 ‘or’

透過使用 -not-or 選項可以更精確地搜尋。

  • 查找被 yexca 所有但不屬於 yexca 群組的檔案:
1
find /home -user yexca -not -group yexca -ls
  • 被 yexca 所有且大於 1GB 的檔案:
1
find /home -user yexca -and -size +1G -ls
  1. 查找檔案和執行指令

透過使用 -exec 選項,可以在每一個找到的檔案執行指令而不必確認,或使用 -ok 以確認是否執行該指令。兩者語法相同:

1
2
find [options] -exec command {} \;
find [options] -ok command {} \;

其中 {} 表示被找到的檔名,可多次使用。在指令末尾需要使用 \; 。例如:

1
find /etc -iname passwd -exec echo "I found {}" \;

查找名為 passwd 的檔案並在 echo 的輸出中包含該名稱。

註:若想了解更多,請使用 man find 指令。

5.2.3 使用 grep 指令在檔案中搜尋

使用 grep 指令可以搜尋包含某一文字 (搜尋內容) 的檔案。搜尋時,可以把包含文字的所有行印出,或只列印相關檔案。grep 還可以搜尋標準輸出。

選項描述
-i忽略大小寫
-v搜尋不包含指定文字的行
-r遞迴搜尋某目錄的檔案
-l僅顯示檔名
–color醒目提示搜尋文字 (預設為紅色)
  • 在 /etc/sysconfig 目錄遞迴搜尋文字 root:
1
grep -ri --color root /etc/sysconfig/
  • 從標準輸出中搜尋包含 inet 的行:
1
ip addr show | grep inet