0%

Linux (四) - 檔案與目錄操作

Linux (二) - 檔案系統架構 中,我們有介紹過了幾個用來操作檔案和目錄的基本指令,lscdmkdir。這一篇要來介紹更多常用的檔案和目錄操作指令。

路徑

操作檔案必須要先知道檔案的路徑才能進行存取,而存取檔案的路徑可以分為絕對路徑和相對路徑。

絕對路徑

絕對路徑就是直接指定路徑,例如 : /home/user1/test.txt

相對路徑

相對路徑通常是用於退回到前幾層再去訪問其他的目錄,退回前一層的方式是加上 ../。所以相對路徑看起來就會像是 ../../user1/test.txt

如果是要指定當前路徑則是 .

切換路徑

有了路徑之後就可以透過 cd 指令切換路徑,例如 : cd /home/user1 就可以切換到 user1 目錄下。

更多切換路徑的範例請參考 Linux (二) - 檔案系統架構

常用命令

以下介紹一些常用的命令,由於 Linux (二) - 檔案系統架構 已經介紹過 lscdmkdir 了,這裡就不在介紹,如果你還不了解這些指令建議先去看一下。

pwd

pwd (print work directory) 用於顯示目前所在的目錄名稱。

1
$ pwd [-P]

-P 是可以選擇的參數,如果有加會列出真實的路徑,所以如果是連結檔(捷徑),就不會列出連結檔路徑而是檔案原本的位置。

範例

1
2
$ pwd
/home/testDir

rmdir

rmdir (remove directory) 用於刪除空的目錄。

1
$ rmdir [-p]

-p 是可以選擇的參數,如果有加可以直接刪除上一層空的目錄。

範例
首先先建立兩層的目錄,接者用 rmdir 指定刪除第二層 testDir,完成後列出當前目錄會發現第一層目錄 testDir1 還在。所以如果希望連第一層都刪掉的話就必須加上 -p 參數,執行完後會發先第一層目錄 testDir1 已經連同第二層一起被刪掉了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ mkdir testDir1

$ mkdir testDir1/testDir2

$ rmdir testDir1/testDir2

$ ls
testDir1

$ mkdir testDir1/testDir2

$ rmdir -p testDir1/testDir2

$ ls

cp

cp (copy) 用於複製檔案或目錄,而預設複製的檔案的權限會將擁有者設定給操作指令的使用者。

1
cp [option] source|[source] [destination]

option :

  • -a : 會完整複製檔案,包含權限設定,如果是複製目錄則會複製目錄下所有檔案,等同 -pdr 三個功能。
  • -d : 若來源檔是連結檔,則會複製連結檔屬性而不是文件本身。
  • -f : 強制 (force) 複製,如果目標文件已經存在且無法開啟則會移除後再試一次。
  • -i : 若目標檔已經存在則覆蓋前會先詢問。
  • -l : 建立實體連結檔到目標檔案。
  • -p : 連同文件屬性一起複製,非使用預設的屬性,常用於備份。
  • -r : 遞迴持續複製,也就是會將整個目錄下的所有檔案都複製。
  • -s : 複製成為符號連結檔 (symbolic link),就是捷徑。
  • -u : 目標比來源舊才更新,或是目標檔不存在才複製。

範例
下面是一個最簡單的範例,單純將 test1.txt 複製到 testDir1 目錄下。

1
2
3
4
$ cp test1.txt testDir1

$ ls testDir1
test1.txt

下面這個範例先將 test1.txt 的檔案擁有者換成 user1,而當前的使用者是 user2,可以看到複製完後檔案的擁有者變成了 user2

1
2
3
4
5
6
7
8
9
10
user2@myComputer$ chown user1 test1.txt

user2@myComputer$ ls -l test1.txt
-rw-r--r-- 1 user1 group1 0 Sep 30 06:33 test1.txt

user2@myComputer$ cp test1.txt testDir1

user2@myComputer$ ls -l testDir1
total 0
-rw-r--r-- 1 user2 group1 0 Sep 30 07:25 test1.txt

接著我們加入 -a-f 參數,-a 是為了測試加了 -a 之後權限是否不會被改掉,而 -f 則是不需要刪掉先前的檔案,可以強制覆蓋過去。可以看到最後檔案的擁有者還是維持 user

1
2
3
4
5
6
7
8
9
10
user2@myComputer$ chown user1 test1.txt

user2@myComputer$ ls -l test1.txt
-rw-r--r-- 1 user1 group1 0 Sep 30 06:33 test1.txt

user2@myComputer$ cp -af test1.txt testDir1

user2@myComputer$ ls -l testDir1
total 0
-rw-r--r-- 1 user1 group1 0 Sep 30 07:25 test1.txt

下面這個範例加入 -i 參數,可以看到因為檔案已經存在了,所以會先詢問是否要覆寫。

1
2
$ cp -ai test1.txt testDir1
cp: overwrite 'testDir1/test1.txt'?

接下來在來實測 -a 是否真的會複製目錄下所有檔案,這裡要先自行將要被複製的目錄新增多層目錄及添加檔案。可以看到原本 testDir3 是沒有檔案的,複製完後目錄下多了不只一層且含有檔案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ mkdir testDir3

$ ls -l testDir3
total 0

$ cp -a testDir1 testDir3

$ ls -l testDir3
total 4
drwxr-xr-x 4 root root 4096 Sep 30 09:28 testDir1

$ ls -l testDir3/testDir1
total 8
-rw-r--r-- 1 tony root 0 Sep 30 06:33 test1.txt
-rw-r--r-- 1 root root 0 Sep 30 09:28 test2.txt
drwxr-xr-x 2 root root 4096 Sep 30 09:28 testDir2
drwxr-xr-x 2 root root 4096 Sep 30 09:28 testDir3

另外像是 -p-r 其實也是可以透過組合成 -pr 變成 -a,所以如果是要完整複製一模一樣的檔案或是目錄可以直接使用 -a 就好。

rm

rm (remove) 用於刪除檔案或目錄。

1
rm [option] [file/folder]

option :

  • -f : 強制 (force) 刪除,不會出現警告訊息。
  • -i : 互動 (interactive) 模式,刪除前會先詢問使用者。
  • -r : 遞迴 (recursive) 刪除,用於刪除目錄,但也非常危險。

範例
首先先刪除檔案,可以看到 -i 其實不一定要加,預設就會在刪除前詢問是否要刪除。

1
2
$ rm -i test1.txt
rm: remove regular empty file 'test1.txt'? y

接著使用 -f 強制刪除可以發現並不會詢問是否要刪除。

1
rm -f test3.txt

最後來測試刪除資料夾,可以發現直接刪除是會失敗的,所以如果是刪除資料夾一定要加 -r

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ rm -i testDir1
rm: cannot remove 'testDir1': Is a directory

$ rm -r testDir1
rm: descend into directory 'testDir1'? y
rm: descend into directory 'testDir1/testDir2'? y
rm: remove regular empty file 'testDir1/testDir2/test1.txt'? y
rm: remove directory 'testDir1/testDir2'? y
rm: remove regular empty file 'testDir1/test2.txt'? y
rm: descend into directory 'testDir1/testDir3'? y
rm: remove regular empty file 'testDir1/testDir3/test3.txt'? y
rm: remove directory 'testDir1/testDir3'? y
rm: remove regular empty file 'testDir1/test1.txt'? y
rm: remove directory 'testDir1'? y

mv

mv (move) 用於移動檔案或目錄,也可以用來修改名稱。

1
2
mv [option] [source] [destination]
mv [option] source|[source] [directory]

option :

  • -f : 強制 (force) 覆蓋,如果目標 (destination) 檔案已經存在會直接覆蓋不會詢問。
  • -i : 互動 (interactive) 模式,如果目標檔案已經存在,會先詢問是否覆蓋。
  • -u : 更新 (update) 檔案,如果目標檔案已經存在且來源 (source) 檔案比較新才會更新。

範例
首先先建立一些測試用的檔案和資料夾,這個範例我們先測試使用 -f 參數,可以看到在不經詢問下 testmv 最後順利移動到了 mvDirTest1 資料夾中。

1
2
3
4
5
6
7
8
9
10
11
$ touch testmv testmv2
$ ls
testmv testmv2

$ mkdir mvDirTest1 mvDirTest2
$ ls
mvDirTest1 mvDirTest2 testmv testmv2

$ mv -f testmv mvDirTest1
$ ls mvDirTest1
testmv

接著為了測試 -i 參數的詢問是否覆蓋已經存在的檔案,再次新建立一個 testmv,並移動到 mvDirTest1,可以看到會在移動前詢問是否覆蓋已經存在的 testmv

1
2
3
$ touch testmv
$ mv -i testmv mvDirTest1
mv: overwrite 'mvDirTest1/testmv'? y

除了移動檔案到資料夾下,也可以移動資料夾到另一個資料夾中,如下 :

1
2
3
$ mv mvDirTest1 mvDirTest2
$ ls mvDirTest2
mvDirTest1

mv 指令也可以重新命名檔案,概念其實就是將現有檔案移到一個新的檔案就算是重新命名,如下 :

1
2
3
$ mv testmv2 testmv21
$ ls
mvDirTest1 mvDirTest2 testmv21

進階檔案操作命令

前面介紹了一些常用的檔案基本命令,下面要來介紹幾個比較進階的命令。

touch

touch 指令可以用於新增空白檔案也可以用來更改檔案的時間戳記。但是較常用的就是用來建立空白檔案,所以更改檔案時間戳記的做法請參考 Linux Touch命令的8種常見用法

1
touch file|[file]

範例
touch 指令建立檔案可以一次建立多個,在先前的一些範例也都有出現過,只要指定好檔名即可。

1
2
3
$ touch t1.txt t2
$ ls
t1.txt t2

cat

cat (concatenate) 指令可以用於顯示檔案內容建立檔案合併檔案內容

顯示檔案內容

1
cat [option]

option :

  • -A : 等於 -vET,可以列出一些特殊字元而不是空白而已。
  • -b : 列出行號,空白行不標行號。
  • -E : 將結尾的段行 $ 顯示出來
  • -n : 列出行號,包含空白行也有行號。
  • -T : 將 tab^I 顯示。
  • -v : 列出一些看不出的特殊字元。

範例
加上 -b 參數,可以看到只有非空行會顯示行數。

1
2
3
4
5
6
$ cat -b testcat
1 This is a test.

2 this is a test.

3 This is a tab test.

加上 -n 參數,可以看到每一行都會顯示行數。

1
2
3
4
5
6
7
$ cat -n testcat
1 This is a test.
2
3 this is a test.
4
5 This is a tab test.
6

加上 -E 參數,可以看到每一行都會有 $ 符號代表換行。

1
2
3
4
5
6
7
$ cat -E testcat
This is a test.$
$
this is a test.$
$
This is a tab test.$
$

加上 -T 參數,可以看到 This is a^Itab^Itest. 這行被加上了 ^I 代表那一格是 tab

1
2
3
4
5
6
$ cat -T testcat
This is a test.

this is a test.

This is a^Itab^Itest.

建立檔案

cat 指令建立檔案和 touch 不同的是 cat 在建立時可以直接輸入檔案內容而 touch 只會建立空檔案,需要在建完後再開啟檔案編輯。如果用 cat > 對一個已經存在的檔案下命令的話會直接將舊的內容覆蓋掉,這點要特別注意。

1
cat > [file]

範例
直接建立一個檔案並輸入內容,最後輸入 Ctrl+D 結束輸入。輸入完後可以再用 cat 指令列出來看,如下 :

1
2
3
4
5
6
7
8
9
10
$ cat > file1
this is file1.

hello world!
[Ctrl+D]

$ cat file1
this is file1.

hello world!

合併檔案內容

cat 指令也可以用於合併多個檔案的內容。

1
cat [file]... > [NewFile]

範例
下面這個範例可以看到最後新的 textfile3textfile1textfile2 的內容合併在了一起。

1
2
3
4
5
6
7
8
9
$ cat textfile1
this is file1
$ cat textfile2
this is file2

$ cat textfile1 textfile2 > textfile3
$ cat textfile3
this is file1
this is file2

加入內容到檔案後面

前面提到 cat > 可以用來建立檔案並且直接輸入內容,而如果是要加資料到檔案的後面可以直接使用 cat >> 來加入。

1
cat >> [file]

範例
下面這個範例可以看到先建立了一個 file.csv 的檔案,並且輸入內容。接著再用 cat >> 輸入一筆內容,最後輸出資料就多了一筆新增的內容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ cat > file.csv
id,name,sex
1,frank,male
2,simon,male

$ cat file.csv
id,name,sex
1,frank,male
2,simon,male

$ cat >> file.csv
3,mary,female

$ cat file.csv
id,name,sex
1,frank,male
2,simon,male
3,mary,female

more

more 指令可以用於檔案內容大於螢幕輸出視窗時,不會一次顯示全部內容導致看不到前面的內容。而是先顯示部分內容,再透過操作繼續顯示後面的內容。

1
more [file]

在 more 指令執行的過程中可以使用以下幾個按鍵操作 :

  • Enter : 向下翻一行。
  • Space : 空白鍵代表向下翻一頁。
  • / : 斜線後加上字串可以向下搜尋,例如 : /net 是在搜尋 net 這個字串。
  • b : 往回翻頁。
  • q : 立刻離開 more。

範例
下面的範例可以看到最後一行的 --More--(26%),這是代表目前顯示的內容量,游標也會在此,所以就可以透過 EnterSpace 等等的按鍵進行操作。

1
2
3
4
5
6
7
8
9
10
11
$ more anaconda-post.log

Loaded plugins: fastestmirror, ovl
No Match for argument: dhclient
No Match for argument: dhcp-common

...

---> Package python-firewall.noarch 0:0.6.3-8.el7_8.1 will be erased
--> Running transaction check
--More--(26%)

less

less 指令可以讓檔案輸出時擁有分頁的功能,類似於 more 指令。但是 more 指令如果要往前翻只能一次翻一頁,而 less 指令更有彈性,可以任意的前後翻。此外還可以任意的進行搜索。

1
less [file]

在 less 指令執行的過程中可以使用以下幾個按鍵操作 :

  • Enter : 向下翻一行。
  • Space : 空白鍵代表向下翻一頁。
  • / : 斜線後加上字串可以向下搜尋,例如 : /net 是在搜尋 net 這個字串。
  • pagedown : 向上翻一頁。
  • pageup : 向下翻一頁。
  • q : 立刻離開 more。

範例
下面這個範例可以很明顯看到沒有像 more 指令一樣最後一行會有 --More--(26%),而且在輸出上會快很多,因為 more 是一次載入完才顯示而 less 是要看的時候才載入。

1
2
3
4
5
6
7
8
9
10
$ less anaconda-post.log

Loaded plugins: fastestmirror, ovl
No Match for argument: dhclient
No Match for argument: dhcp-common

...

---> Package python-firewall.noarch 0:0.6.3-8.el7_8.1 will be erased
--> Running transaction check :

vi

vi 是一個文字編輯器,經常用於編輯檔案的內容。

1
vi [file]

在執行 vi 編輯器時,可以透過以下按鍵進行操作 :

  • IOA : 代表要輸入 (Insert) 內容,vi 編輯器剛開啟檔案時是預覽模式不能編輯,一定要先按下 IOA 才可以開始編輯。
  • Esc : 從輸入模式切換回預覽模式,編輯完後必須先切換回預覽模式。
  • :q : 離開 vi 編輯器。
  • :w : 儲存變更,將編輯過的內容寫進檔案,可以結合 :q 變成 :wq,寫入後直接離開。
  • ! : 強制執行,可以搭配 :w:q 使用。

範例
使用 vi 編輯器打開檔案後會呈現出檔案的內容,此時是預覽模式不能編輯。

1
2
3
4
5
6
7
$ vi textfile3

this is file1
this is file2
~
~
"textfile3" 2L, 28C

要編輯時按下 IOA 就可以開始編輯,並且底部會出現 -- INSERT --

1
2
3
4
5
this is file1
this is file2
~
~
-- INSERT --

編輯完後要先按下 Esc 鍵離開編輯模式,並且輸入 :w:q 等等的命令,輸入的命令會顯示在最後一行。

1
2
3
4
5
this is file1
this is file2
~
~
:wq

Summary

本篇介紹了一些常用的檔案操作命令,透過這些命令就可以對檔案進行複製、移動、刪除、編輯等等的操作。如此就可以更方便的對這些檔案進行管理和使用了。

參考

[1] Linux 文件與目錄管理
[2] Linux 檔案與目錄管理 | 鳥哥
[3] Linux touch命令
[4] Linux Touch命令的8種常見用法
[5] Linux cat命令用法
[6] vim 程式編輯器 | 鳥哥
[7] linux中的cat,more,less指令使用