[TOC]
# 文件及目錄操作相關命令
## 文件、目錄及路徑的概念
> 說到文件、目錄其實大家都會有大概的一個概念,比如記錄日記的一頁紙是一個文件、記錄今天行程的便簽是一個文件,而為了避免文件亂丟亂放找不到,我們會將這些文件都收納到了不同的文件夾中保存,這就是我們日常生活中的對文件和文件夾的理解,那么在計算機中也是類似的道理。
### 什么是文件
>專業的定義是: 文件是在邏輯上具有完整意義的信息集合,它有一個文件名以供標識,文件名是以字母開頭的字母數字串。
> 首先是一個信息集合,比如我們編寫的辦公文檔、命令程序,他們都是信息的集合,其次是邏輯上具有完整意義,能夠完整的表達這個文件的信息價值,比如命令程序文件可以被運行,文檔可以被文檔解析軟件正確解析,一個被損壞的文件是布局有完整意義的,例如我們下載的視頻文件因為沒有下載完成而無法被解析成功,下載途中的圖片無法被圖片軟件解析等等。
文件是文件系統中對信息數據管理的基本單位,文件是具有格式的,不同的文件格式在操作系統中表示不同的意義。
例如: 一個圖片文件與一個文本文件的文件格式是不同的,在Windows系統中通常是通過文件擴展名`.jpg`和`.txt`區分,Linux系統下也是可以通過文件名后綴識別不同文件格式的。
### 什么是目錄(文件夾)
`目錄`也叫做`文件夾`,用來對文件數據的分類存放,這樣不同的目錄下可以分別存放不同類型的數據,比如`/etc`目錄用于存放配置類文件數據,`/usr/bin/`存放的都是可執行程序文件數據,你可以自定義`視頻`或者`圖片`等目錄來分類你的個人文件數據。
### 根目錄
Unix/Linux系統的目錄結構是從`/`開始的樹形結構(也叫作`root目錄`或根目錄,以后了解文件系統時會深入了解)。目錄之間使用斜杠`/`分隔,而不是Windows中的反斜杠`\`。root目錄`/`下有子目錄,如/usr、/home、/tmp等等。

### 什么是路徑(絕對路徑與相對路徑)
當我們想要訪問某一個目錄或文件時,首先要知道它的存放位置,這個位置就是存放的`路徑`,路徑分為兩種:`絕對路徑`和`相對路徑`。
- `絕對路徑`就是以`/`根目錄開始表示的路徑,無論我們當前的工作路徑在哪里,都可以使用絕對路徑正確訪問。
- `相對路徑`就是不以`/`開始表示的路徑,例如`code/python_test.py`、`./code/github/README.md`或者`../config/test.conf`,當我們更換了`當前工作目錄`后需要同時修改`相對路徑`信息才可以再次正確訪問目錄或文件。
注意: 當我們使用`相對路徑`時,如果不以`..`或`.`開頭需要在`$PATH`環境變量中添加`.`當前工作目錄才可以正確使用`相對路徑`,例如我們想在當前目錄下執行一個`hello.sh`腳本:
```sh
$ echo $PATH
/home/user/bin:/usr/local/bin:/usr/bin:/bin
$ hello.sh
hello.sh 命令沒找到
$ ./hello.sh
hello world!
$ export PATH=$PATH:.
$ echo $PATH
/home/user/bin:/usr/local/bin:/usr/bin:/bin:.
$ hello.sh
hello world!
```
### 重要的目錄
下面這些目錄需要重點介紹。
- `/bin`目錄中存放的是可執行文件,包括大部分基礎的Unix命令(如ls和cp)。該目錄中的大部分是由C編譯器創建的二進制文件,還有一些現代系統的shell腳本文件。
- `/dev`目錄中是設備文件,磁盤、輸入輸出設備等等。
- `/etc`目錄存放重要的系統配置文件,如用戶密碼文件、啟動文件、設備、網絡和其他配置文件。
- `/home`目錄中是用戶的個人目錄。大多數Unix/Linux系統都遵循這個規范。
- `/lib`目錄中是供`32位`可執行程序使用的各種代碼庫。代碼庫分為兩種:靜態庫和共享庫。`/lib`目錄中一般只有共享庫。
- `/lib64`目錄中是供`64位`可執行程序使用的各種代碼庫。
- `/usr`目錄存放著許多Linux系統文件。`/usr`目錄中的很多子目錄目錄名和root目錄上的相同(如`/usr/bin`和`/usr/lib`等等),你可以在`/bin`目錄下看到很多命令其實是軟鏈接到了`/usr/bin`目錄下的命令的(為了讓root文件系統占用盡可能少的空間,也是方便命令程序的更新管理)。
- `/proc`目錄中通過一個可瀏覽的目錄與文件接口來存放系統相關信息,比如當前運行的進程和內核的信息。Linux上這個目錄的一大部分子目錄結構相比其他Unix系統要特別一些,但其他Unix系統大多也有類似的特性。/proc目錄中包含了當前正在運行的進程的信息以及一些內核參數。
- `/sbin`目錄中是可執行的系統文件,這些可執行文件用來管理系統。普通用戶一般不需要使用,許多命令只能由`root`用戶運行。
- `/tmp`目錄存放的是臨時文件。所有用戶對該目錄都有讀和寫的權限,不過可能對別人的文件沒有權限。許多程序會使用這個目錄作為保存數據的地方,但如果數據很重要的話請不要存放在/tmp目錄中,因為很多系統會在啟動時清空/tmp目錄,甚至是經常性地清理這個目錄里的舊文件。也注意不要讓/tmp目錄里的垃圾文件占用太多的硬盤空間。
- `/var`目錄是程序存放運行時信息的地方,如系統日志、用戶信息、緩存和其他信息。(你可能會注意到這里有一個子目錄/var/tmp,和/tmp不同的是,系統不會在啟動時清空它。)
- `/boot`目錄存放內核加載文件。這些文件中存放Linux在第一次啟動時的信息,之后的信息并不保存在這里。
- `/opt`目錄一般存放第三方軟件,許多系統并沒有這個目錄。
## 操作文件及目錄的命令
> 文件及目錄操作命令可能是我們使用最多的命令了,因為我們需要跟文件和目錄打交道最多。所以掌握這些命令算是學習Linux系統的基礎。
### Shell通配符
shell可以使用`通配符`來匹配文件名和目錄名。其他的操作系統也有通配符這個概念。當我們`對文件名或目錄名不太確定具體值`或者`批量操作文件或目錄`時就可以使用通配符來匹配。
通配符有:
- `*` : 匹配0個或多個任意字符(包括字母、數字和符號)。
- `?` : 匹配`1`個任意字符(包括字母、數字和符號)。
舉例來說:
1. 列舉當前目錄所有以`A`開頭的文件或目錄: `ls -ld A*`
2. 列舉當前目錄所有名字格式為`?ata.txt`的文件或目錄: `ls -ld ?ata.txt`(可能是Data.txt或data.txt等等)
### 查看當前目錄內容-ls
> 這是我們使用最多的一個命令了,因為在操作目錄下文件之前先要知道木對應目錄下有哪些文件或目錄。
下面是查看當前目錄信息的示例:
```sh
# 在一行列舉當前目錄下的所有文件及目錄(不包括以.開頭的隱藏文件)
$ ls
# 逐行列舉當前目錄下的所有文件及目錄(不包括以.開頭的隱藏文件)的詳細信息
$ ls -l
# 逐行列舉當前目錄下的所有文件及目錄(包括以.開頭的隱藏文件)的詳細信息
$ ls -al
```
我們還可以使用`-t`參數按文件最后修改時間信息排序(先列舉新文件),使用`-r`參數逆向排序(先列舉舊文件),如下:
```sh
$ ls -tl
$ ls -trl
```
參數`-d`,可以防止進一步列舉指定目錄內的信息,減少遞歸深入訪問目錄層次:
```sh
$ ls -ld ./*
drwxr-xr-x 2 zioer users 6 9月 8 00:42 ./公共
drwxr-xr-x 2 zioer users 6 9月 8 00:42 ./模板
drwxr-xr-x 9 zioer users 267 12月 8 22:39 ./視頻
drwxr-xr-x 3 zioer users 4096 12月 14 15:42 ./圖片
drwxr-xr-x 9 zioer users 238 12月 20 15:57 ./文檔
drwxr-xr-x 8 zioer users 4096 12月 19 12:45 ./下載
drwxr-xr-x 2 zioer users 6 9月 8 00:42 ./音樂
drwxr-xr-x 2 zioer users 73 12月 10 11:14 ./桌面
```
### 訪問目錄-cd
`cd`命令用來設置`當前工作目錄`。`當前工作目錄`是指你的進程和shell當前所在的目錄。
```sh
$ cd /tmp
```
如果不帶dir參數,cd命令會返回你的`默認工作目錄`(`$HOME`變量指定目錄),指的是你登錄系統后進入的目錄。
在`Linux`系統中:
- 符號`.`表示`當前目錄`。
- 符號`..`表示當前目錄的`上級目錄`(也叫父目錄)。
- 符號`~`表示默認工作目錄(`$HOME`目錄)。
- 符號`-`表示切換上次訪問的目錄(`$OLDPWD`環境變量對應的目錄)
### 查看當前目錄的絕對路徑-pwd
這個命令沒有任何參數,執行后顯示當前工作目錄的絕對路徑:
```sh
$ pwd
/tmp
```
### 創建目錄-mkdir
最簡單的目錄創建命令:
```sh
$ mkdir ./download
$ mkdir ./download/{video,image,software}
```
上面新建兩級目錄,執行了兩次`mkdir`命令,可以使用`-p`參數批量創建多級子目錄(如果其中子目錄不存在就創建):
```sh
$ mkdir -p ./download/{video,image,software}
```
### 刪除目錄-rmdir
```sh
$ rmdir ./download/{video,image,software}
$ rmdir ./download
```
同`mkdir`一樣,可以使用`-p`參數遞歸刪除子目錄:
```sh
$ rmdir -p ./download/{video,image,software}
```
> 注意:`rmdir`命令刪除目錄時需要先清空目錄內的文件或子目錄,否則會`目錄非空`報錯信息。
> 如果想刪除非空目錄需要使用`rm -rf `命令刪除,但是前提是你一定清楚要刪除的是什么內容。
### 移動或重命名文件及目錄命令-mv
將目錄從一個路徑`移動`到另一個路徑下,或者將一個目錄名`重新命名`為另一個目錄名,這時我們會使用到`mv`命令
```sh
$ mv 源文件或目錄 新目錄名
$ mv 源文件 目標文件
```
如果我們想把多個文件存放到一個目錄下的命令如下:
```sh
$ mv 文件1 文件2 ... 目標目錄
```
如果可能會有文件名同名時,而你的確想要覆蓋掉`目標目錄`的文件時,可以使用`-f`選項參數強制用新文件覆蓋掉`目標目錄`下原有的文件。
```sh
$ mv -f 文件1 文件2 ... 目標目錄
```
> 說明: 可能你會發現`mv`命令有時候移動文件很長一段時間才完成,而有時即使移動的文件特別大時也能瞬間完成,原因在哪里呢?
這可能跟操作的`源文件`與`目標目錄`是否在同一個文件系統下有關,
- 同一個文件系統下的移動文件或目錄可以理解為位置或名稱的變化,而數據不會移動。
- 不同文件系統下的移動文件或目錄就需要先在目標文件系統的目錄下新建文件,然后將數據復制到新文件中,最后刪除源文件,所以會耗時長一些。
### 復制文件或目錄命令-cp
`cp`命令用來復制文件。下面的命令將文件file1復制到文件file2:
```sh
$ cp file1 file2
```
下面的命令將多個文件(file1 ... fileN)復制到目錄dir:
```sh
$ cp file1 ... fileN dir
```
### 文件格式信息參看命令-file
> linux系統的命令文件常常會不攜帶文件名后綴,那么我們如何識別文件格式呢?答案是使用`file`命令。
- 可以查看文件格式類型: 是文本文件、圖片、視頻或者二進制文件等等。
- 可以確定可執行程序是32位還是64位。
- 可以查看可執行程序是否可執行程序或者動態庫是否剔除了符號信息(使用的函數等信息),可以通過分析使用的庫函數來分析某些功能的實現邏輯。
我們可以通過`file`命令來查看文件格式信息:
```sh
$ file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=89963a71cfc1f2da28f8cbc218d92f8b624c808d, for GNU/Linux 3.2.0, stripped
$ file Linux_Installation_Instructions.pdf
Linux_Installation_Instructions.pdf: PDF document, version 1.3
$ file 2019-09-26-raspbian-buster-lite.zip
2019-09-26-raspbian-buster-lite.zip: Zip archive data, at least v2.0 to extract Zip archive data, at least v2.0 to extract
```
我們可以了解到`ls`命令是64位的`x86_64`架構可執行程序、pdf文檔和zip壓縮文件,知道了正確的文件格式才能夠使用正確的解析方法。
### 修改文件的時間戳信息-touch
一個文件有三個時間戳信息:
- 最后訪問時間(atime) : 最后讀取文件內容的時間。
- 最后修改時間(mtime) : 最后寫入文件內容的時間。
- 最后變更時間(ctime) : 最后修改文件屬性信息的時間,例如`chmod`,`chown`。
```sh
# 新建文件或者更新已有文件的最后修改時間戳到當前系統時間
$ touch filename
# 自定義修改文件的時間戳信息(默認是最后修改時間戳,-a參數為最后訪問時間)
# CC為年數中的前兩位,YY為年數后兩位,MM為月份,DD為天數,hh為小時數(24小時),mm為分鐘,SS為秒數(0-61)
$ touch -t [[CC]YY]MMDDhhmm[.SS] filename
$ touch -a -t [[CC]YY]MMDDhhmm[.SS] filename
# -r reffile 可以將參考文件`reffile`的時間信息作為指定文件filename的新時間戳。
touch -r ref_file filename
```
### 實時查找文件命令-find
當我們想要查找某一個文件名的存放路徑時就會使用`find`命令:
```sh
$ find ./ -name "config.xml" -type f
```
這是最簡單的查找命令了,常見參數有:
- `-type` : 查找文件類型(f:文件, d:目錄, p:命名管道,l:符號鏈接, s:套接字, b:塊文件, c:字符文件)
- `-size` : 查找文件大小,可以攜帶 +/-符號表示大于/小于,單位可以有b:塊(默認512字節),k:表示KB, M:表示MB, G:表示GB.
- `-name` : 查找的名字匹配規則
- `-mtime`: 查找文件的最后修改時間天數,例如+/-表示大于/小于, 0表示當前系統時間的24小時(86400秒)以內。
- `-newer`: 查找比參數設置的參考文件最后修改時間新的文件。
- `-exec` : 對查找的結果要執行的下一個命令,例如對查找文件執行刪除操作, `find ./ -name "*.txt" -type f -exec rm -f {} \;`
- `-follow`: 不檢索符號鏈接。
- `-depth`: 先處理目錄的內容再處理目錄本身。
對于一些復雜的條件可能還需要邏輯關系:
- `expr1 -a expr2` : expr1 并且 expr2
- `expr1 -o expr2` : expr1 或者 expr2
- `! expr` : expr條件的非運算
- `( expr )` : 括號表達式,解決符號或條件優先級問題,注意空格分割開。
### 根據索引查找文件命令-locate
`locate`命令是根據名稱到文件索引庫中匹配查找,特點是查找速度快,但是缺點是可能由于數據庫更新頻率滿問無法實時查找到最新的文件位置。
### 文件路徑的拆分命令-basename和dirname
例如一個文件路徑`/tmp/config.conf`
- 獲取存放的目錄`/tmp`的命令: `dirname /tmp/config.conf`
- 獲取文件名稱`config.conf`的命令: `basename /tmp/config.conf`
### 修改文件的權限命令-chmod
### 修改文件的屬主命令-chown
### 連接文件內容并輸出的命令-cat
當我們想把兩個文件內容按先后順序合并輸出時,可以使用`cat`命令:
```sh
cat file1 file2
```
### 查看文件的開始和末尾部分命令-head與tail
head命令顯示文件的前10行內容(例如head /etc/passwd)。tail命令顯示文件的最后10行內容(如tail /etc/passwd)。
你可以使用-n選項來設置顯示的行數(例如:head -5 /etc/passwd)。如果要從第n行開始顯示所有內容,使用tail +n。
### 統計文件磁盤占用大小的命令-du
```sh
$ du file
1024 file
# 遞歸統計當前目錄下所有文件及目錄占用磁盤情況(-h參數以人類可讀格式展示,按文件大小顯示單位K/M/G)
$ du -h ./*
# 只統計當前目錄(不遞歸統計)的所有文件及目錄磁盤使用情況
$ du -sh ./*
```
### 統計磁盤使用率情況的命令-df
> 為了防止磁盤空間被占滿,我們會經常查看磁盤的使用情況,可以使用`df`命令
```sh
$ df -h /
文件系統 容量 已用 可用 已用% 掛載點
/dev/mapper/system-root 30G 24G 6.3G 79% /
```
### 分頁查看文件的命令-more和less
> 有時我們只想查看或查找文件內容,并不想修改它,此時可以使用more或less命令。
`more`命令可以以分頁方式查看文件內容,輸入`/`加`keyword`查找關鍵詞keyword所在位置。
`less`命令與`more`功能相似,差別在于`more`只能單向閱讀,而`less`可以雙向上、下閱讀。
## 總結
以上命令都是非常基礎的命令,也非常簡單易用,學習的時候只需要在Linux系統中實際操作幾次后就可以學會。如果想要更詳細了解具體參數的信息,可以使用`man`命令查看命令的幫助文檔。
---
~END~
- 前言
- 第一章 開始吧
- 1.0 選擇適合你的Linux發行版
- 1.1 開始制作啟動U盤
- 1.2 安裝你的第一個Linux操作系統
- 1.3 安裝Linux系統后要做的事情
- 1.4 什么是root用戶
- 1.5 Linux下使用終端執行Shell命令
- 1.6 Linux軟件安裝方法介紹
- 1.7 Linux常用軟件推薦
- *安裝Manjaro發行版系統
- *安裝Manjaro后要做的配置工作
- Flatpak安裝軟件方法
- 為什么Linux系統普及成都落后于Windows和MacOS?
- 第二章 Linux上的基礎命令
- 2.0 環境變量及配置相關命令
- 2.1 文件及目錄操作相關命令
- 2.2 文本處理相關命令
- 2.3 進程任務管理相關命令
- 2.4 用戶管理相關命令
- 第三章 開發環境的部署
- 3.0 學習Shell編程
- 3.1 環境變量配置實例_如何配置JDK環境
- Python編程環境
- C語言編程環境
- 第四章 深入理解Linux系統
- 關于Linux不得不說的CopyLeft