Files
Obsidian-Main/21.01. OS/21.01. Linux/CLI/cut.md
Awin Huang 5d4e261181 vault backup: 2025-07-22 22:14:08
Affected files:
Too many files to list
2025-07-22 22:14:08 +08:00

173 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## cut
Linux 的 `cut` 指令是一個實用的文字處理工具,可以將每一行文字的部份字元或欄位擷取出來,以下是使用方式與範例。
### 擷取字元
對於欄位寬度是固定的資料,可以使用擷取固定位置字元的方式,把指定的欄位抓出來,典型的例子就是從 `ls` 指令的輸出中擷取檔案權限。假設我們的 `ls` 指令與輸出資料如下:
```bash
# 僅輸出最後 5 筆檔案資訊
ls -l | tail -n 5
```
```
drwxr-xr-x 2 gtwang gtwang 4096 11月 7 22:29 影片
drwxr-xr-x 7 gtwang gtwang 4096 2月 6 21:01 文件
drwxr-xr-x 4 gtwang gtwang 4096 2月 22 21:09 桌面
drwxr-xr-x 2 gtwang gtwang 4096 1月 6 2017 模板
drwxrwxr-x 2 gtwang gtwang 4096 1月 6 2017 音樂
```
如果我們想要擷取第一欄中的檔案權限(也就是第 2 個字元到第 10 個字元),可以使用 `cut` 指令配合 `-c` 參數,將每一行的第 2 個字元至第 10 個字元抓出來:
```bash
# 擷取第 2 個字元至第 10 個字元
ls -l | tail -n 5 | cut -c 2-10
```
Output:
```
rwxr-xr-x
rwxr-xr-x
rwxr-xr-x
rwxr-xr-x
rwxrwxr-x
```
如果要擷取多個不連續的的區段,逗號分隔每個區段,例如:
```bash
# 擷取第 2-3 個、第 5-6 個與第 8-9 個字元
ls -l | tail -n 5 | cut -c 2-3,5-6,8-9
```
Output:
```
rwr-r-
rwr-r-
rwr-r-
rwr-r-
rwrwr-
```
### 排除字元
上面的範例中我們都是設定要擷取的部份,如果想要設定排除的部份,可以加上 `--complement` 這個補集參數,這樣 `cut` 就會將指定的部份刪除,留下剩餘的部份:
```bash
# 排除第 2 個字元至第 10 個字元
ls -l | tail -n 5 | cut -c 2-10 --complement
```
Output:
```
d 2 gtwang gtwang 4096 11月 7 22:29 影片
d 7 gtwang gtwang 4096 2月 6 21:01 文件
d 4 gtwang gtwang 4096 2月 22 21:09 桌面
d 2 gtwang gtwang 4096 1月 6 2017 模板
d 2 gtwang gtwang 4096 1月 6 2017 音樂
```
### 擷取欄位
若我們的資料欄位寬度不是固定的而是使用特定的字元分隔不同的欄位例如逗點分隔檔csv 檔):
```
5.1,3.5,1.4,0.2,"setosa"
4.9,3,1.4,0.2,"setosa"
7,3.2,4.7,1.4,"versicolor"
6.4,3.2,4.5,1.5,"versicolor"
5.9,3,5.1,1.8,"virginica"
```
若要擷取這個 csv 檔的特定欄位,可以使用 `cut` 指令加上 `-d` 參數指定欄位分隔字元,並以 `-f` 參數指定欲擷取的欄位,例如擷取出第 2 個欄位:
```bash
# 擷取 CSV 檔的第二個欄位
cut -d , -f 2 data.csv
```
Output:
```
3.5
3
3.2
3.2
3
```
若要擷取多個欄位,也是使用逗號分隔每個欄位:
```bash
# 擷取 CSV 檔的第 1-3 個與第 5 個欄位
cut -d , -f 1-3,5 data.csv
```
```
5.1,3.5,1.4,"setosa"
4.9,3,1.4,"setosa"
7,3.2,4.7,"versicolor"
6.4,3.2,4.5,"versicolor"
5.9,3,5.1,"virginica"
```
Linux 中的 `/etc/passwd` 檔案內容是以冒號分隔欄位的,若要從中擷取特定的欄位,可以指定以冒號為分隔字元:
```bash
# 擷取 /etc/passwd 的第 1 個與第 7 個欄位
head -n 5 /etc/passwd | cut -d : -f 1,7
```
```
root:/bin/bash
daemon:/usr/sbin/nologin
bin:/usr/sbin/nologin
sys:/usr/sbin/nologin
sync:/bin/sync
```
### 排除欄位
若要排除某些特定欄位,而留下其餘的欄位,同樣可以使用 `--complement` 參數:
```bash
# 排除 CSV 檔的第二個欄位
cut -d , -f 2 --complement data.csv
```
```
5.1,1.4,0.2,"setosa"
4.9,1.4,0.2,"setosa"
7,4.7,1.4,"versicolor"
6.4,4.5,1.5,"versicolor"
5.9,5.1,1.8,"virginica"
```
### 輸出分隔字元
`cut` 在輸出多欄位的資料時,預設會以輸入檔案所使用的分隔字元來分隔輸出的欄位,若要改變輸出欄位的分隔字元,可以使用 `--output-delimiter` 參數來指定:
```bash
# 指定輸出欄位分隔字元
head -n 5 /etc/passwd | cut -d : -f 1,7 --output-delimiter="^_^"
```
```
root^_^/bin/bash
daemon^_^/usr/sbin/nologin
bin^_^/usr/sbin/nologin
sys^_^/usr/sbin/nologin
sync^_^/bin/sync
```
### 實用範例
Linux 的系統管理者時常會需要使用 `ps` 指令查看各行程的狀態,但由於 `ps` 的輸出資訊很多,如果我們只想看程式的 PID 與指令內容,就可以用 `cut` 把要用的資訊擷取來:
```bash
# 找出所有 Python 程式的 PID 與指令內容
ps aux | grep python | sed 's/\s\+/ /g' | cut -d ' ' -f 2,11-
```
```
17100 grep --color=auto python
27904 /usr/bin/python -Es /usr/sbin/tuned -l -P
33890 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
```