Linux 檔案命令

檔案與目錄

witch

沒有這個 witch (巫婆) 命令啦,老是將 which (哪一個) 打成 witch。
那卡住了怎麼辦? ls 應該記得起來吧,另再記兩個目錄 /bin/usr/bin

$ls \bin\w*
ls: cannot access 'binw*': No such file or directory
又打錯了,改成斜線 (/)。
$ls /bin/w*
/bin/wdctl  /bin/which  /bin/whiptail

好!看到了 which 是在 /bin/which

/bin/which 去找 which
/bin/which which
/usr/bin/which

疑?用 /bin/which 去找 which 結果是 /usr/bin/which

看一下 path
$echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

原來執行 which 時是按 path 搜尋,先找 /usr/bin 再找 /bin,預設行為是找到後就不再繼續執行。

which 有沒有可以找出全部的 path 的參數?
$which -h
Illegal option -h
Usage: /usr/bin/which [-a] args
$which --help
Illegal option -h
Usage: /usr/bin/which [-a] args
好吧!應該就是 -a 吧,一個說明都要這麼省。
which -a which
找到了兩個路徑
/usr/bin/which
/bin/which
列示 /usr/bin/which
$ls /usr/bin/which -l
lrwxrwxrwx 1 root root 10 2019-10-21 13:23 /usr/bin/which -> /bin/which

/usr/bin/which 是連結至 /bin/which,不過這裡有點疑問,linux 已經把 /bin 納入 PATH 了, 不知道為什麼還要在 /usr/bin 做連結,也許是要讓學習 linux 困難一點?

journalctl 這個命令這麼長,老是忘記,來一個 ls 吧!
$ls /bin/j*
/bin/journalctl
journalctl 又有連結? 幸好沒有,要不然全亂了。
$which -a journalctl
/bin/journalctl

which 太方便了,好吧!建一個 Windows which。

which.cmd
@setlocal
@set P2=.;%PATH%
@for %%e in (%PATHEXT%) do @for %%i in (%~n1%%e) do @if NOT "%%~$P2:i"=="" echo %%~$P2:i

不過也不需要啦,Windows 用 where 即可。

ls 檢視目錄與檔案

ls [選項] [檔案或目錄]
ls 選項

-l

以每行列出詳細資料

-h, --human-readable

以高可讀性顯示檔案容量大小 (如 1K 2M 3G)。

-a, --all

顯示所有檔案,含隱藏檔。

-A, --almost-all

顯示所有檔案,但不包括 ... 這兩個目錄。

-d, --directory

列出該目錄而不是目錄內的檔案。

-R, --recursive

遞迴,含目錄內的所有檔案。

-r, --reverse

排序時倒序。

-t

依時間排序。

-S

依檔案容量大小排序。

-F, --classify

加入指示字元,如將目錄後置 /

-i, --inode

列出實際儲存於檔案系統中的索引碼,可參閱後文的硬連結

設定 ls 顯示時間格式 long-iso,顯示時間格式如為 2038-01-19 03:47。
export TIME_STYLE=long-iso
處理目錄內 .txt 的範例
for F in $(ls *.txt); do \
echo $F; \
done

cp 複製

cp [參數] 來源 目的
cp 選項

-r, -R

遞迴,含目錄內的所有檔案。

-p

複製檔案 (或目錄) 的擁有者及群組 (ownership),檔案權限 (mode) 及時間 (timestamps),擁有者及群組僅限超級用戶 (即為 root) 才會複製。

-d

保留檔案連結 (跟 --no-dereference --preserve=links 相同)。

--preserve=links

保留檔案連結。

--preserve=all

連同特殊屬性 (擁有者、群組、檔案權限、時間、連結、xattr) 一併複製,擁有者及群組僅限超級用戶 (即為 root) 才會正確。

-a

-dR--preserve=all 相同

-L, --dereference

複製連結檔的實際檔案。

-P, --no-dereference

複製軟連結 (never follow symbolic links in SOURCE)。

--parents

保留來源目錄結構。

-f, --force

強制執行,在無法寫入目的檔案時,嘗試刪除目的檔案後,再次重新複製 (同時具有 -n 選項時,本選項將被忽略)。

--remove-destination

先刪除目的檔案,再執行複製。

-n, --no-clobber

不要覆蓋現有的檔案。

-i, --interactive

在覆蓋檔案之前,先詢問。

-u, --update

更新,當來源比「目的」新或「目的」缺少才會複製。

-l, --link

將檔案複製成硬連結。

-s, --symbolic-link

將檔案複製成軟連結。

-S, --suffix=SUFFIX

指定備份檔的結尾名稱,未指定為 ~

-b, --backup

備份目的檔案 (若目的檔案已存在,將目的檔名增加結尾名稱,如果結尾名稱的檔案已存在,先刪除再改名)。

基本操作
檔案複製
cp 來源檔案 目的檔案
將檔案複製到其他目錄,可指定目的目錄 (保留原始檔案名稱)
cp 來源檔案 已存在的目的目錄/
多檔複製
cp 來源檔1 來源檔2 來源檔3 已存在的目的目錄/
複製目錄
cp -r /path/folder 新增的目的目錄

當目的目錄不存在時則複製至該目的目錄。
但如果目的目錄存在則複製至該目錄內,遞迴複製目錄內容,需在來源目錄後增加一個 * (通配字元)。

遞迴複製目錄內容
cp -r /path/folder/* 已存在的目的目錄 (1)
1 /path/folder/* 改為 /path/folder/,則複製至 已存在的目的目錄/folder
cp 預設行為
  • 擁有者及群組 (ownership) 權限為操作帳戶。

  • 複製檔案權限 (mode)

  • 將硬連結轉成一般檔案。

  • 複製軟連結。

  • 覆蓋檔案且不會詢問。

  • 不會刪除目的目錄的多餘檔案。

不要覆蓋現有的檔案
不要覆蓋現有的檔案 -n,檔案已存在,並不會執行複製。
cp -n source.txt dest.txt
或者在覆蓋檔案之前,先詢問 -i
$cp -i source.txt dest.txt
cp: overwrite 'dest.txt'?
更新檔案 (-u),來源檔案的修改時間比目的檔案還新,或者目的檔案缺少,則更新檔案
cp -u source.txt dest.txt
-iur 來得知目錄內那些檔案需要更新
$cp -iur source/*  dest
cp: overwrite 'dest/source.txt'?
強制覆蓋檔案
如果目的檔案檔案無法寫入(如權限為唯讀),則無法執行複製。
$cp soruce.txt dest.txt
cp: cannot create regular file 'dest.txt': Permission denied
-f 強制執行
cp -f soruce.txt dest.txt
--remove-destination 先刪除目的檔案,再執行複製。
cp --remove-destination soruce.txt dest.txt
備份目的檔案

覆蓋目的檔案時,若需備份可採用 -b 備份目的檔案。

備份目的檔案 -b
cp -b source.txt dest.txt

預設會將目的檔案的結尾名稱加上 ~,例如 dest.txt 會備份至 (改名為) dest.txt~,如果 dest.txt~ 已存在,則先刪除 dest.txt~ 再將 dest.txt 改名。指定備份結尾檔名以 -S 來設定。

指定備份目的檔案 -S .bak
cp -b -S .bak source.txt dest.txt

dest.txt 則備份至 dest.txt.bak,如果 dest.txt.bak 已存在,則先刪除 dest.txt.bak 再將 dest.txt 改名。

複製連結檔案

複製檔案時,複製連接檔案的目標檔案,可採用 -L 複製連結檔的目標檔案,複製後為一般檔案。
link.txt 是指向 source.txt 的連結檔,dest.txt 實際上是複製 source.txt

-L 複製連結檔的目標檔案。
cp -L link.txt dest.txt

在複製軟連結檔案時,將軟連結直接複製,可採用 -P 複製軟連結,如 soft-link 是一個軟連結,複製後的 dest.txt 亦為軟連結檔案。

這裡為什麼要強調是連結?
因為硬連結會複製成一般檔案。

-P 複製軟連結
cp  -P soft-link.txt dest.txt

保留檔案連結 -d 的情況比較複雜,當硬連結的目標檔案在相同的目錄一起被複製時,則以硬連結複製,其他情況則轉成一般檔案。
如在 source 目錄內,檔案 source.txt 的硬連結為 link.txt,在目錄中建立硬連結 other-link.txt 連結至 other/source.txt

列出測試目錄的內容
$ls other source -liU
other:
total 4
2935287 -rw-rw-r-- 2 ubuntu ubuntu 4 1970-01-01 08:00 source.txt

source:
total 12
2935287 -rw-rw-r-- 2 ubuntu ubuntu 4 1970-01-01 08:00 other-link.txt
2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 1970-01-01 08:00 source.txt
2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 1970-01-01 08:00 link.txt
以保留檔案連結 -d,將目錄 source 複製至目錄 dest
$cp -rd source dest

$ls dest/source.txt dest/link.txt dest/other-link.txt -liU
2935289 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 13:43 dest/source.txt (1)
2935289 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 13:43 dest/link.txt (1)
2935290 -rw-rw-r-- 1 ubuntu ubuntu 4 2023-03-12 13:43 dest/other-link.txt (2)
1 硬連結的原始檔一起被複製,則會以硬連結複製。
2 不在相同的目錄則會轉成一般檔案。
以參數 -d 複製 dest/link.txtdest/dest.txtdest/dest.txt 視為一般檔案。
$cp -d dest/link.txt dest/dest.txt

$ls dest/dest.txt -li
2935291 -rw-rw-r-- 1 ubuntu ubuntu 4 2023-03-12 14:42 dest/dest.txt
以軟、硬連結複製檔案

以參數 -s 將檔案複製成軟連結,等同於 ln -s 命令建立連結,link.txt 是一個指向 source.txt 的連結檔。

將檔案複製成軟連結 -s
cp -s source.txt link.txt

以參數 -l 將檔案複製成硬連結,等同於 ln 命令建立連結,link.txtsource.txt 的分身 (inode 相同)。

將檔案複製成硬連結 -l
cp -l source.txt link.txt
cp 建立連結比 ln 的好處是可一次建立目錄下多個連結。
cp -sr $PWD/source soft-dest
cp -lr source hard-dest
複製擁有者及群組、檔案權限及時間

複製擁有者、群組、檔案權限及時間 -p-a,以超級用戶 (即為 root) 運作時,擁有者及群組權限才會複製。

複製檔案權限及時間 -p
sudo cp -p source.txt dest.txt
複製檔案權限及時間及保留連結 -a
sudo cp -a source.txt dest.txt
保留來源目錄結構
--parents 保留來源目錄結構。
mkdir -p path/to
touch path/to/source.txt
mkdir dir-parents

cp --parents path/to/source.txt dir-parents/
$tree path (1)
path
└── to
    └── source.txt

$tree dir-parents
dir-parents
└── path
    └── to
        └── source.txt
1 若沒有 tree 命令,以 sudo apt install tree 安裝。

scp 安全複製遠端目錄與檔案

scp 是 secure copy 的縮寫,基於 ssh 安全通訊複製遠端的檔案 (目錄)。

scp 命令的語法跟 cp 類似,scp 可在主機之間複製檔案,其語法為:
scp [[來源帳號@]來源主機:]來源檔案或目錄 [[目的帳號@]目的主機:]目的檔案或目錄

省略帳號與主機,表示本機的檔案,只省略帳號表示本地端的使用者帳號跟遠端帳號一樣。

scp 選項

-r

遞迴,含目錄內的所有檔案。

-p

保留檔案時間

-C

壓縮之後再傳送

-l

限制網路頻寬,單位為 Kbit/s。

-p

複製原始檔案的修改時間、存取時間和檔案權限 (mode)。

基本操作

ubuntu 帳號登入 192.168.1.1 主機,將主機上的 /path/file 複製到本地端的 /path/file
本地端的使用者帳號跟遠端的使用者帳號一樣時,可省略使用者帳號。

從遠端檔案複製到本地端
scp ubuntu@192.168.1.1:/path/file /path/file
在執行命令時,會以 SSH 登入遠端的主機,需輸入 ubuntu@192.168.1.1 的密碼 (公開金鑰連接 SSH 服務器除外):
ubuntu@192.168.1.1's password:
從遠端檔案複製到本地端,省略帳號
scp 192.168.1.1:/path/file /path/file

複製方向相反也類似。

由本地端檔案複製到遠端
scp /path/file 192.168.1.1:/path/file
從遠端目錄複製到本地端
scp -r 192.168.1.1:/path/folder 新增的目的目錄

當目的目錄不存在時則複製至該目的目錄。
但如果目的目錄存在則複製至該目錄內,遞迴複製目錄內容,需在來源目錄後增加一個 * (通配字元)。

遞迴複製目錄內容
scp -r 192.168.1.1:/path/folder/* 已存在的目的目錄 (1)
1 若把 /path/folder/* 改成 /path/folder/,則複製至 已存在的目的目錄/folder
複製檔案權限 (mode) 及時間 -p
scp -p 192.168.1.1:/path/file /path/file
限制傳輸速度為 100 Kbit/s
scp -l 100 192.168.1.1:/path/file /path/file (1)
1 -l 跟數字之間,可不需要空白字元。
將資料壓縮之後再傳送 -C
scp -C 192.168.1.1:/path/file /path/file
SSH 服務的連接埠號為 22,改為自訂連接埠 222。
scp -P 222 192.168.1.1:/path/file /path/file

rm (刪除)、mv (移動或改名)

rm
rm 移除的檔案或目錄
rm 選項

-r, -R

遞迴,含目錄內的所有檔案。

-f

強制刪除不會詢問。

mv
mv 移動(或改名)來源 目的

mv 是 move 的縮寫,除了移動的功能外也可以重新命名。將「來源」移動至「目的」,如果「目的」為存在的檔案則會被覆蓋。

ln 檔案連結

通過連結檔案,不同的檔名可以指向同一個檔案。連結類型分為硬連結 (hard link) 和符號連結 (symbolic link) 兩種,符號連結也稱軟連結 (soft link),預設的連結類型是硬連結。

軟連結

軟連結為一個獨立的檔案或目錄,類似於 Windows 作業系統中的捷徑方式。
軟連結本身有檔案屬性及權限。
軟連結可以跨檔案系統。
軟連結可以對目錄進行連結。
刪除軟連結並不影響目標檔案,若目標檔案被刪除,則相關軟連結被稱為已斷開的懸掛連結 (dangling link),當重新建立目標時則懸掛連結可恢復為正常。
建立不存在目標的軟連結 (跟懸掛連結相似),不會提示錯誤 (註:ls 會將指向顯示成紅色)。
絕對路徑所建立的連結檔,在搬移軟連結檔時目標位置會相同,而以相對路徑建立的連結檔,其目標位置則會變動。

ln 語法
ln [參數] 目標(TARGET) 連結名稱(LINK_NAME)

本文中將「連結名稱」指向的檔案 (或目錄) 稱為「目標」。
「連結名稱」為「軟連結」或「硬連結」。

ln 選項

-s, --symbolic

建立軟連結。

-r, --relative

建立相對路徑的軟連結。

-P, --physical

建立成硬連結 (預設值,不需指定本參數)。

-f, --force

強制執行 (連結存在時先刪除檔案)。

-i, --interactive

交互模式,連結存在時提示是否取代。

-S, --suffix=SUFFIX

指定備份檔名的結尾名稱,未指定為 ~

-b, --backup

備份連結檔案 (若連結檔案已存在,將連結檔名增加結尾名稱,如果結尾名稱的檔案已存在,先刪除再改名)。

-v, --verbose

顯示詳細的處理過程

建立軟連結

以參數 -s,將 source.txt 建立 softlink.txt 軟連結檔。

建立軟連結 -s
ln -s source.txt softlink.txt

連結至不同目錄,建立的「目標」是相對於「連結名稱」的路俓。

source 目錄中建立一個 source.txt 檔案,並建立一個 dest 目錄
mkdir source
echo 123 > source/source.txt
mkdir dest
dest 目錄中,建立相對路徑目標 ../source/source.txt 的軟連結 RelLink1.txt
cd dest
ln -s ../source/source.txt RelLink1.txt

在目錄中,建立的目標很直覺會採用正確的相對路徑。
但如果在目錄外往往會出錯。

建立錯誤的軟連結 ErrorLink.txt
cd ..
ln -s  source/source.txt dest/ErrorLink.txt
正確的「目標」是「連結名稱」位置的相對路俓 (當做目前路徑是「連結名稱」的目錄內)。
ln -s ../source/source.txt dest/RelLink2.txt
或者以 -r 建立相對路徑的軟連結。
ln -sr source/source.txt dest/RelLink3.txt
建立絕對路徑的 AbsLink.txt
ln -s $PWD/source/source.txt dest/AbsLink.txt
顯示 dest 目錄內建立的軟連結檔案。
$ls dest -li
total 0
2906099 lrwxrwxrwx 1 ubuntu ubuntu 35 2023-03-12 20:32 AbsLink.txt -> /home/ubuntu/demo/source/source.txt
2893916 lrwxrwxrwx 1 ubuntu ubuntu 17 2023-03-12 20:31 ErrorLink.txt -> source/source.txt
2893902 lrwxrwxrwx 1 ubuntu ubuntu 20 2023-03-12 20:31 RelLink1.txt -> ../source/source.txt
2894388 lrwxrwxrwx 1 ubuntu ubuntu 20 2023-03-12 20:31 RelLink2.txt -> ../source/source.txt
2894401 lrwxrwxrwx 1 ubuntu ubuntu 20 2023-03-12 20:32 RelLink3.txt -> ../source/source.txt
建立硬連結
建立目標為 source/source.txtdest/HardLink.txt 硬連結
ln -P source/source.txt dest/HardLink.txt (1)
1 -P 為預設值,可不需要該參數。

硬連結是使用相同的 inode,沒有相對路徑的問題。

顯示 source/source.txt dest/HardLink.txt 的 inode
$ls source/source.txt dest/HardLink.txt -lU --inode
2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 20:05 source/source.txt
2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 20:05 dest/HardLink.txt

兩個不同檔案,實際儲存於檔案系統中的索引碼 (inode) 為 2935285,在檔案權限後面的數字 2 表示該檔案有 2 個硬連結。

刪除硬連接 (應該說刪除其中一個分身)
$rm source/source.txt (1)

$ls dest/HardLink.txt -lU --inode
2935285 -rw-rw-r-- 1 ubuntu ubuntu 4 2023-03-12 21:05 dest/HardLink.txt
1 或者以 unlink 刪除連接,執行 unlink source/source.txt

刪除 source/source.txt 後,前面範例的軟連接已變成了懸掛連結 (dangling link)。
刪除 (以 rmunlink) dest/HardLink.txt 後,由於檔案實體沒有分身,則為實際刪除該檔案。

重建 source/source,回復原始狀態。
$ln dest/HardLink.txt source/source.txt

$ls source/source.txt dest/HardLink.txt -lU --inode
2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 21:05 source/source.txt
2935285 -rw-rw-r-- 2 ubuntu ubuntu 4 2023-03-12 21:05 dest/HardLink.txt

find 找出合乎模式的檔案

搜尋目錄之下合乎條件的檔案或目錄。
find [path…​] [expression],expression 包含了林林總總的各式參數,全部混在一起。

find --help
find ... [path...] [expression]
expression may consist of: operators, options, tests, and actions

operators ...
      EXPR1 -o EXPR2   EXPR1 -or EXPR2   EXPR1 , EXPR2

normal options (在其他參數之前先指定 options):
      -depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf

tests ...
      -ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN

actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print

find 的參數有不少,可用 man find 取得詳細說明。

tests (測試參數)
名稱符合

-name PATTERN: 檔案名稱符合 PATTERN,-iname 不區分大小寫。
-path PATTERN: 目錄名稱符合 PATTERN,-ipath 不區分大小寫。
目錄名稱包含了 / (斜線),如 -ipath '*/some-path/*' 表示找出目錄名稱 some-path 的檔案,而 -ipath '*/some*/*' 則找出目錄名稱前置 some

檔案、目錄名稱符合 PATTERN 的外框需加單引號 (') 或雙引號 (")。否則;要轉譯正規表示法的特殊字元'*.txt' 要轉譯成 \*\.txt
檔案類型符合

-type [bcdpflsD]: 類型參數 f 檔案,l 連結檔,d 目錄…​ 。

檔案時間符合

-amin 讀取分鐘,-atime 讀取天數,-cmin 修改分鐘,-ctime 修改天數
-ctime n: 檔案在 n 天前修改過。
-ctime +1: +n 大於 n,所以是 2 天前修改過。
-ctime -n: 「減」表示跟目前的時間比較,在最近的 n 天內修改過的檔案。

檔案大小符合

-size +10M -size -20M,大於 10M 小於 20M 檔案。單位:k Kilobytes,M Megabytes,G Gigabytes。

測試參數可不少直接查閱 find --help,像找出擁有者 -user,擁有群組 -group,檔案權限 -perm。

找出目前路徑及子路徑內的 .txt 檔案
find . -iname '*.txt' (1)
1 目前路徑可以不輸入 .
operators (運算式)
-a-and

AND (及) 邏輯,可不需要該運算式,expr1 -a expr2expr1 expr2 相同

找出最近一分鐘修改的 .txt
find -iname '*.txt' -a -cmin -1
find -iname '*.txt' -cmin -1
-o-or

OR (或) 邏輯

找出 .txt 或 .doc 檔案:
find -iname '*.txt' -o -iname '*.doc'

找出 .txt 或 .doc 檔案,以長格式顯示:
find -iname '*.txt' -ls -o -iname '*.doc' -ls

當運算式同時有 AND、NOT、OR 時,AND、NOT 先判斷之後再判斷 OR。
如果 OR 兩邊有相同條件,兩邊都要加入;另外 actions 也一樣兩邊都要加入。

!-not

NOT (否定) 邏輯

找出不為 .txt 的檔案:
find ! -name '*.txt'

找出擁有者不為 www-data 的檔案:
find ! -user 'www-data'

找出檔案權限不為 775 或目錄權限不為 775:
find -type f -not -perm 775 -o -type d -not -perm 775
find -type f -not -perm 775 -ls -o -type d -not -perm 775 -ls
actions (動作)
find -iname '.log' -ctime 7 -delete (1)
find -iname '.log' -ctime -7 -ls (2)
1 刪除 7 天前 .log 檔案
2 以長格式列出 7 天內的 .log 檔案
-exec 執行命令語法格式
  • -exec 命令 {} \;

  • -exec 命令 {} +
    先 (前置) 輸出檔案名稱,再執行命令。

其中的字串 {} 會替換成檔案名稱。

找出 7 天內有 error 記錄的 .log 檔案
find -iname '.log' -ctime -7 -exec grep error {} \;
find -iname '.log' -ctime -7 -exec grep error {} +
options (選項)

-maxdepth LEVELS,最大階層。
-mindepth LEVELS,最小階層。
註:options 需要在其他參數之前先指定。

找出目前路徑的 .txt 檔案
find . -maxdepth 1 -iname '*.txt'

rsync 遠端同步檔案與目錄

rsync 主要用於同步 (鏡像) 檔案與目錄,傳輸時比對內容僅複製差異檔案,可減少資料傳輸量。
可保留檔案的擁有者、群組與權限設定,刪除多餘的目的檔案或目錄。

安裝 rsync
apt install rsync
rsync 語法
rsync [[來源帳號@]來源主機:]來源檔案或目錄 [[目的帳號@]目的主機:]目的檔案或目錄

省略帳號與主機,表示本機的檔案,只省略帳號表示本地端的使用者帳號跟遠端帳號一樣。

rsync 參數說明

--archive, -a

備份模式;遞迴備份所有子目錄下的目錄與檔案,保留連結檔、檔案的擁有者及群組 (ownership)、檔案權限 (mode) 以及時間戳記,跟 -rlptgoD 相同。
擁有者及群組僅限超級用戶 (即為 root) 才會同步。

--recursive, -r

遞迴,含目錄內的所有檔案。

--links, -l

保留軟連結。

--perms, -p

保留檔案權限 (mode)。

--times, -t

保持時間戳記。

--group, -g

保留擁有群組 (僅限超級用戶,即為 root)。

--owner, -o

保留擁有者 (僅限超級用戶,即為 root)。

-D

same as --devices --specials

--devices

preserve device files (僅限超級用戶,即為 root)。

--specials

preserve special files.

參數 -a 有不少 (以上) 功能,而且是最重要的參數,可以說是必備參數,如果沒有該參數要花很多時間測試。

--hard-links, -H

保留硬連結。

--verbose, -v

詳細模式輸出。

--human-readable, -h

以可讀性較高的方式來顯示 (需配合 -v)。

--prune-empty-dirs, -m

不複製空目錄。

--compress, -z

傳輸過程中壓縮檔案。

--dry-run, -n

測試執行。

--delete

刪除多餘的目的檔案或目錄。

--chmod

設定檔案或目錄權限,如 --chmod=775

--chown

設定擁有者及群組,如 --chown=www-data:www-data

--info=progress2

傳輸時以單行顯總體進度 (man rsync)。

--itemize-changes, -i

顯示每個檔案的變動摘要。

--rsh=COMMAND, -e

設定遠端登入指令。

--bwlimit=RATE

限制網路頻寬,RATE 可指定如 1.5m,未指定單位時如 100,則為 100K。

基本操作
同步檔案,將檔案 file 同步至 dest/file,會自動建立 dest 目錄。
rsync -a /path/to/file dest/
同步目錄,將目錄 d1 同步至 d2/d1,會自動建立 d2 目錄。
rsync -a /path/to/d1 d2

若需將目錄 d1 同步至目錄 d2,同步目錄內容需在來源目錄後增加 / (斜線) 或是 /* (斜線及通配字元)。
當需要目錄複製 (同步) 至目錄時,可採用 rsync 並在來源目錄增加 /,不管目的目錄是否存在,只會複製至目的目錄。

同步來源目錄內容,將目錄 d1 同步至目錄 d2,會自動建立 d2 目錄。
rsync -a /path/to/d1/ d2
rsync -a /path/to/d1/* d2

ubuntu 帳號登入 192.168.1.1 主機,將主機上的 /path/folder 複製到本地端的 dest
本地端的使用者帳號跟遠端的使用者帳號一樣時,可省略使用者帳號。
可增加 -z 參數,將資料壓縮後再傳輸,減少網路傳輸的資料量。

從遠端目錄同步到本地端
rsync -az ubuntu@192.168.1.1:/path/folder/ dest
在執行命令時,會以 SSH 登入遠端的主機,需輸入 ubuntu@192.168.1.1 的密碼 (公開金鑰連接 SSH 服務器除外):
ubuntu@192.168.1.1's password:
同步擁有者及群組、檔案權限

-a 已經具備了該功能,以超級用戶 (即為 root) 執行 rsync 時則能同步。

同步本地目錄檔案用戶權限
sudo rsync -a /path/to/d1/ d2
ubuntu 同步遠端目錄
rsync -az /path/to/folder/ ubuntu@192.168.1.1:/path/to/folder
同步遠端帳戶為 ubuntu,若目的已存在而擁有者及群組不為 ubuntu 時則會引發錯誤,如下
rsync: failed to set permissions
rsync: failed to modify permissions
rsync: failed to set times on
遠端帳戶為 root,遠端目的檔案或目錄的擁有者會同步。
rsync -az /path/to/folder/ root@192.168.1.1:/path/to/folder
同步時指定目的權限為 775,擁有者及群組為 www-data:www-data
rsync -az --chmod=775 --chown=www-data:www-data /path/to/folder/ root@192.168.1.1:/path/to/folder
當本地的檔案權限超出了登入帳戶權限,而以 sudo 執行時,也表示遠端帳戶也需要以 root 帳戶登入,那麼可不需要「目的帳號」。
sudo rsync -az /path/to/folder/ 192.168.1.1:/path/to/folder
顯示檔案變動摘要 (--itemize-change-i)
$rsync --itemize-change -a /path/to/d1 d2
.d..tp..... ./
>f+++++++++ f1.txt
>f..tp..... fh1.txt
>f..tp..... fh2.txt
cL+++++++++ fs1.txt -> f1.txt
cL+++++++++ fs2.txt -> ../d2/f2.txt
>f..t...... r1.txt

檔案項目之前會多出 11 個字元,分別為 YXcstpoguax
意義如下:

Y 異動類型

<

檔案傳送至遠端

>

本地端接收檔案

c

代表本地端變動(如建立目錄、軟連結)

h

代表本地端建立硬連結(hard link)

.

代表沒有變動(但可能有變動其他屬性)

*

代表其餘欄位有包含訊息(例如 deleting)

X 檔案型態

f

一般檔案

d

目錄

L

軟連結檔

D

設備檔(device)

S

特殊檔案(如 sockets 或 fifo)。

cstpoguax 說明

c

內容變更。

s

大小變更。

t

時間戳記變更。

o

擁有者變更。

p

檔案權限 (mode) 變更。

g

群組變更。

u

保留欄位。

a

ACL 變更。

x

擴充屬性(extended attribute)變更。

其他值

.

無變更

+

新增檔案或目錄

YXcstpoguax 示例
.d..t......

. 項目沒有變動(儘管它變更了其他屬性)
d 目錄類型
t 時間變更

>f.st......

> 接收檔案
f 一般檔案
s 大小變更
t 時間變更

cd+++++++++

c 建立目錄
d 目錄類型
+++++++++ 新增目錄

>f+++++++++

> 接收檔案
f 一般檔案
+++++++++ 新增檔案

cL+++++++++

c 建立軟連結檔
L 軟連結檔
+++++++++ 新增軟連結檔

hf..t......

h 建立硬連結
f 一般檔案
t 時間變更

可以同時測試執行(--dry-run-n),事先得知同步的情況
$rsync --dry-run -ai /path/to/d1 d2

created directory d2
cd+++++++++ ./
>f+++++++++ f1.txt

sent 236 bytes  received 63 bytes  598.00 bytes/sec
total size is 30  speedup is 0.10 (DRY RUN)
設定遠端登入指令 (-e)
192.168.1.1 主機的 SSH 服務連接埠為 222,以選項 -e 設定遠端登入指令
rsync -az -e 'ssh -p 222' ubuntu@192.168.1.1:/path/folder/ dest

遠端登入的預設指令為 ssh,參考 ssh 命令加入選項 -p,將指令變更為 ssh -p 222 以連接埠 222 登入 SSH。

同步副檔名及階層
同步多個副檔名,原始目錄下 (第一層) 的檔案,子目錄並不會同步
rsync \
--include="*.svg" \ (1)
--include="*.png" \
--include="*.jpg" \
--include="*.jpeg" \
--exclude='*' \ (2)
$srcPath $destPath
1 指定合乎的副檔名。
2 最後條件請按範例。
複製原始目錄 (所有) 第 2 層的副檔名
rsync \
--include='/*/' \ (1)
--exclude='/*' \  (2)
--include="*.svg" \
--include="*.png" \
--include="*.jpg" \
--include="*.jpeg" \
--exclude='*' \
$srcPath $destPath
1 包含 1 ~ 2 層 ( 第 1 層是指原始目錄下的檔案,第 2 層為原始目錄的子目錄 )。
2 排除第 1 層 (先包含階層再排除)。
包含階層說明
rsync \
--include='*/' \ (1)

rsync \
--include='/*/' \ (2)
--include='/*/*/' \ (3)
--include='/*/*/*/' \ (4)
1 包含所有階層
2 包含 1 ~ 2 層。
3 包含第 3 層 (必須先包含 1 ~2 層,才有作用)。
4 包含第 4 層 (必須先包含 1 ~2 層及第 3 層,才有作用)。
排除階層
rsync \
--include='*/' \ (1)
--exclude='/*' \ (2)
--exclude='/*/*' \ (3)
--exclude='/*/*/*' \ (4)
1 先包含所有階層再排除
2 排除第 1 層 (個別指定)
3 排除第 2 層 (個別指定,不需要先排除第 1 層)
4 排除第 3 層 (個別指定,不需要先排除第 1 或 2 層)

diff 列出檔案差異

列出兩個檔案或目錄的差異。

diff 語法
diff [參數] ... 檔案或目錄
diff 參數說明

-q, --brief

顯示差異的檔案,不顯示差異內容,可用於比對兩個目錄的檔案。

-r, --recursive

遞迴,含目錄內的所有檔案。

-c, -C[NUM], --context[=NUM]

以「上下文輸出格式」顯示原始檔及新檔案修改的情況,同時列出未變更的行數 (預設為 3)。

-u, -U[NUM], --unified[=NUM]

以「統一格式」輸出原始檔修改情況,同時列出未變更的行數 (預設為 3)。

-n, --rcs

以 RCS 格式顯示 (以新檔案的角度列出修改情況)。

-i, --ignore-case

忽略大小寫。

-b, --ignore-space-change

不檢查空白字元。

-w, --ignore-all-space

忽略所有空白字元,跟 -b 的差異在於直接忽略,如 ABCA B C 不視為差異。

-B, --ignore-blank-lines

忽略空行。

列出兩個目錄中檔案內容不同的檔名 -q
diff -q folder1/ folder2/
Only in folder1: f1.txt
Only in folder2: f2.txt
Files folder1/f3.txt and folder2/f3.txt differ
比對子目錄,加入遞迴 -r 選項
diff -qr folder1/ folder2/
在比對差異內容前,先建立兩個測試檔
cat > org.txt << EOF
line1-org
line2-same
del1
line3-org
del2
line4-same
del3
del4
line5-same
EOF

cat > new.txt << EOF
line1-mod
line2-same
line3-mod
line4-same
line5-same
line6-append
line7-append
EOF
比對差異 diff 第一個參數為原始檔,第二個參數為新檔案。
diff org.txt new.txt
1c1
< line1-org
---
> line1-mod
3,5c3
< del1
< line3-org
< del2
---
> line3-mod
7,8d4
< del3
< del4
9a6,7
> line6-append
> line7-append
1c1 (1)
< line1-org (2)
---
> line1-mod (2)
1 1c1 表示 (原始檔的) 第 1 行換成了 (新檔案的) 第 1 行。
2 < 原始檔內容,> 新檔內容。
3,5c3 (1)
< del1
< line3-org
< del2
---
> line3-mod
1 3,5c3 (原始檔的) 3 至 5 行換成了 (新檔案的) 第 3 行。 , 表示某行至某行,如 3,5c3,3 跟本例一樣,當然開發者不會這樣寫;會合併相同行數。
7,8d4 (1)
< del3
< del4
1 7,8d4 (原始檔的) 第 7 至 8 行刪除成 (新檔案的) 第 4 行。
9a6,7 (1)
> line6-append
> line7-append
1 9a6,7 (原始檔的) 第 9 行新增至 (新檔案的) 6 至 7 行。
diff -u (Unified context) 以「統一格式」輸出原始檔修改情況
diff -u org.txt new.txt
--- org.txt     2020-10-18 14:49:06.997670700 +0800
+++ new.txt     2020-10-18 14:49:07.935176100 +0800
@@ -1,9 +1,7 @@(1)
-line1-org
+line1-mod
 line2-same
-del1(2)
-line3-org
-del2
+line3-mod
 line4-same
-del3
-del4
 line5-same
+line6-append
+line7-append
1 提供給 patch 的資料,當未變更的行數設成 0 時 (-u0),可以發現還是存在 @@ 這些行,該行資料並非是「未變更」。
2 採用 -u 的表現只有 + -空白 沒有模擬兩可的修改情況,del1 (檔案內容) 為刪除。
如果只輸出 + - (不輸出其他) 採用自訂輸出
diff org.txt new.txt \
--old-line-format=$'-%l\n' \
--new-line-format=$'+%l\n' \
--unchanged-line-format=''
diff -c (Copied context) 以「上下文輸出格式」顯示原始檔及新檔案修改的情況
diff -c org.txt new.txt
上方原始檔及下方新檔案的修改情況
*** 1,9 ****
! line1-org
  line2-same
! del1 (1)
! line3-org
! del2
  line4-same
- del3
- del4
  line5-same
--- 1,7 ----
! line1-mod
  line2-same
! line3-mod
  line4-same
  line5-same
+ line6-append
+ line7-append
1 字元符號說明: !(修改) +(新增) -(刪除)、空白(未變更)。
del1 (檔案內容) 是修改跟前面 3,5c3 雖然一致,但是並沒有同時列示該組修改情況,並不知道 del1 實際上是刪除, 採用 -c 需注意該問題,! 可能是刪除 (註:選項 -u 則會標示成刪除 -)。
diff -n (RCS format) 以新檔案的角度列出修改情況
diff -n org.txt new.txt
d1 1 (1)
a1 1 (2)
line1-mod
d3 3 (3)
a5 1
line3-mod
d7 2
a9 2
line6-append
line7-append
1 採用 -n 是以新檔案的角度列示, d1 1 在第 1 行刪除 1 行。
2 a1 1 在第 1 行新增 1 行,不會有修改的情況,「修改」為先「刪除」再「新增」。
3 del1 (檔案內容) 為刪除,以新檔案的角度列示;不關心原始檔,只列出 d3 3 在 3 行刪除 3 行。

patch 補丁

patch 語法
patch [OPTION]... [ORIGFILE [PATCHFILE]]
patch 選項

-o FILE --output=FILE

輸出補丁後的檔案至 FILE

-i PATCHFILE --input=PATCHFILE

讀取 PATCHFILE 補丁檔案 (取代標準輸入 stdin)。

-R --reverse

回復補丁 (已補丁的檔案以 PATCHFILE 回復成補丁前的內容)。

difforg.txtnew.txt 產生補丁檔 org.patch
diff -u org.txt new.txt > org.patch (1)
1 注意!diff 中的 -unified[NUM] 一併列出未變更的行數,不應設定 0,若補丁只有新增時,重複執行可能不會引發錯誤。另外 org.patch 即為前面 Unified context 內容,
org.txtorg.patch 補丁
patch org.txt org.patch
org.txtorg.patch 補丁,輸出至另一個檔案 orgmod.txt
patch org.txt -i org.patch -o orgmod.txt
比對 orgmod.txtnew.txt 應該相同 (即無輸出).
diff -u orgmod.txt new.txt
以選項 -R,將 orgmod.txt 回復成 org.txt
patch orgmod.txt -R -i org.patch
比對 orgmod.txtorg.txt 應該相同
diff -u orgmod.txt org.txt

其他檔案命令 (du df readlink)

du 查看目錄佔用容量

du -hd1 [目錄]
-h 以可讀性較高的方式來顯示。
-d 最大階層

du -hs [目錄]
-s 合計該目錄的總容量。

df 檢查硬碟使用量

df -hl --total
-h 以可讀性較高的方式來顯示。
-l 僅顯示本機的檔案,不納入掛載的檔案。
--total 於最後一行加總
readlink -f 檔案 ...
-f 符號連結正規化 (跟隨檔案的符號連結)
$ readlink -f /usr/bin/which
/bin/which

$readlink -f ~ ~/..
/home/user
/home

輸入與輸出重新導向

輸入與輸出 (I/O) 重新導向是 Linux 系統中非常重要的功能,能夠任意組合各種命令的輸入和輸出及串接任意的「命令管道」(command pipeline)。
在執行命令時,先建立好輸出管道,再建立輸入管道及串接管道。(大部份的命令在) 處理時並非將輸入全部讀取,而是讀取一定的資料量,參與管道的命令「平行處理」輸入與輸出。

>>> 管道輸出
ls > output.txt (1)
date >> output.txt (2)
1 將 ls「標準輸出」至 output.txt 檔案,這裡為什麼稱為 「標準輸出」,因為命令的輸出事實上有「標準輸出」及「錯誤輸出」。
2 日期 輸出附加在檔案尾端 (如果檔案不存在,則會建立新檔案)。
< 管道輸入
cat < input.txt (1)
cat < input.txt > output.txt (2)
1 cat 取得 (由管道輸入) input.txt 資料後輸出至主控台 (顯示於螢幕上)。
2 cat 取得 input.txt 資料後,標準輸出至 output.txt。
一般情況不會這樣寫,會採用由命令讀取檔案的方式 cat input.txt > output.txt
當輸入檔案跟輸出檔案相同時,如果以下列方式執行:
cat file.txt > file.txt

將得到一個空的 file.txt,其原因在於建立管道時,輸出管道 > file.txt 會先執行將建立一個空的 file.txt

<< 管道輸入終止字串
cat > output.txt (1)

cat << EOF (2)
...
EOF
1 cat 需要標準輸入管道,在沒有重導的情況下,表示由主控台 (鍵盤) 輸入,直到輸入終止字元 Ctrl+d
2 由主控台輸入,直到輸入終止字串 EOF。終止字串,可任意命名。
line1='I am the first row'
line2='I am the second row'
cat > output.txt << EOF (1)
$line1
$line2
EOF (1)
1 終止字串沒有雙 (單) 引號的情況下替換變數。
output.txt 的內容如下
I am the first row
I am the second row

接上例,把 EOF 改成 "EOF" 或者 'EOF'

cat > output.txt << "EOF" (1)
$line1
$line2
EOF
1 終止字串有雙 (單) 引號的情況下不會替換變數。
output.txt 的內容如下
$line1
$line2
另外可不採用雙 (單) 引號的終止字串,以反斜線 (\) 禁止轉譯變數。
cat > output.txt << EOF
\$line1
\$line2
EOF
| 串接管道

串接命令操作字元 | 將多個命令串接。串接前一個命令的正確輸出管道;並不能處理錯誤的管道輸出。命令處理後,再傳遞給下一個命令作為標準輸入。串接管道的執行順序是由左至右。

ls | cat -n (1)
ls | cat -n | grep -P '1\t' > output.txt (2)
1 ls 輸出給 cat -n 加上行號後輸出至主控台。
2 串接多個「命令管道」後標準輸出至 output.txt,輸出管道最先執行 (建立),串接管道的執行順序是由左至右,先執行 lscat -n 再執行 grep -P '1\t'
輸入及輸出管道 (各別) 最多只能一個,不可能有多個,下列是將 ls 輸出至 cat 檔案。
ls > cat -n > output.txt

標準及錯誤輸出

一般的 Linux 命令會有三個輸入與輸出的管道,分別為:
  • 標準輸入 (stdin,代號 0):程式輸入管道。
    註:一般命令都具有讀取檔案的功能,讀取檔案並不需要採用 < 來讀取。

  • 標準正常輸出 (stdout,代號 1):命令正常輸出管道。

  • 標準錯誤輸出 (stderr,代號 2):命令出錯或狀態訊息 (可能) 以錯誤管道輸出。

Linux 特殊檔案:
  • /dev/null 是 Linux 空裝置,寫入這個檔案的資料會被直接丟棄,如果從這個檔案讀取資料,則會像讀取空檔案一樣。

  • /dev/stdout 標準正常輸出,即為主控台。

  • /dev/stderr 標準錯誤輸出,也是主控台。

ls 列出不存在的檔案輸出至 output.txt
$ls nonexistent > output.txt
ls: cannot access 'nonexistent': No such file or directory

上述的錯誤訊息就是來自於 ls 的標準錯誤輸出,output.txt 檔案也會建立,不過內容是空的,因為命令沒有任何標準正常輸出。

輸出管道可以採用運算子把正常管道 1> 輸出至指定裝置,或者是錯誤管道 2> 的輸出裝置。
註:標準輸出管道 1> 可不需要指定運算子,1>> 相同。

ls 列出不存在的檔案輸出至 output.txt,錯誤輸出至 error.txt
ls nonexistent 1> output.txt 2> error.txt
可先指定好管道,再傳入參數。
ls 1> output.txt 2> error.txt nonexistent

執行後,主控台看不到任何訊息。

錯誤訊息是在 error.txt
ls: cannot access 'nonexistent': No such file or directory
正常及錯誤輸出至同一裝置,可採用 >&&>,將訊息全部寫入 all.txt
ls output.txt nonexistent &> all.txt
所有訊息在 all.txt
ls: cannot access 'nonexistent': No such file or directory
output.txt
把正常及錯誤管道的訊息輸出至空裝置 /dev/null,不會得到任何訊息。
ls output.txt nonexistent &> /dev/null
合併管道

在執行命令時,可先設定合併管道。
2>&1,將管道 2 導入管道 1。
1>&2,將管道 1 導入管道 2。
要注意 linux 建立輸出管道的順序,是最右邊先建立,「合併管道」要最先執行。

ls output.txt nonexistent 1> all.txt 2>&1

all.txt 的內容跟前面的「所有訊息在 all.txt」一樣。

合併管道順序錯誤範例
ls output.txt nonexistent 2>&1 1> all.txt (1)
1 在主控台可看到錯誤訊息,因為順序不正確。合併管道 2>&1 要最先執行才有作用 (建立輸出管道的順序,是最右邊先建立)。
輸出重導至標準輸出發生權限錯誤
$echo 123 > /dev/stdout
bash: /dev/stdout: Permission denied

$echo 123 > /dev/stderr
bash: /dev/stderr: Permission denied
當登錄為 user1 以 su 切換至另一個 user2 使用者,是造成本問題的原因
su user2

dev/stdout 是一個符號鏈接到 /proc/self/fd/1,再以符號鏈接至偽終端,例如:dev/pts/1。偽終端權限是在登錄時授予,當以 su user2 切換至不同的帳戶時,偽終端的擁有權並不會更改,user2 沒有寫入權限。
註:su root 不會錯誤,超級用戶不受權限影響。

user2 的偽終端權限
$ls /dev/stdout /proc/self/fd/1 /dev/pts/1 -lU
lrwxrwxrwx 1 root   root     15 2023-03-10 04:25 /dev/stdout -> /proc/self/fd/1
lrwx------ 1 user2 user2     64 2023-03-15 11:58 /proc/self/fd/1 -> /dev/pts/1
crw--w---- 1 user1 tty   136, 1 2023-03-15 11:58 /dev/pts/1

檔案內容查閱

cat   顯示檔案所有內容。
head  顯示檔案開頭的內容。
tail  顯示檔案尾端的內容。
more  一頁一頁向後顯示內容 (可向上翻頁僅限檔案,管線無作用)。
less  與 more 類似,但比 more 更容易操作,可前後翻頁。

上述的命令與本文編輯器 (例如 nano 或 vim) 相比,啟動時不需要讀取整個檔案,載入時間會大大縮短,可用於打開大檔案。

cat 顯示檔案所有內容
cat [參數] [檔案]
-n 列印出行號
-E 將行尾的斷行字元以 $ 顯示
-T 將字元 tab 以 ^I 顯示
head 顯示檔案開頭的內容
head -n20 /var/log/auth.log
-n 20, 顯示 20 行,預設為 10 行。
tail 顯示尾端內容
tail -n20 -f /var/log/auth.log
-n 20, 顯示 20 行,預設為 10 行。
-f 持續監控檔案內容,當有新資料時即時顯示。離開監控模式需按下 Ctrl+c 中斷監控。

more 查看命令

more /var/log/auth.log
以下是 more 一些查看時常用的命令:
Shortcut Purpose

q

離開 more

h

顯示說明

Enter

向下一行

空白鍵f

向下翻頁

bCtrl+b

向上翻頁 (僅限檔案,管線無作用)

/ 字串

向前搜尋「字串」

n

重複上一個搜尋 (向前),跟 / 有關。 沒有向後的功能。

less 查看命令

less 一次顯示一頁檔案或命令輸出 (pipe) 的內容,跟 more 相似但具有更好的功能;如可翻頁內容。

less /var/log/auth.log
用管線將說明傳送給 less
rsync --help | less
以下是一些查看時常用的命令:
Shortcut Purpose

q

離開 less

h

顯示說明,離開說明則按下q

PageDown空白鍵f

向下翻頁

PageUpb

向上翻頁

g

至檔案開頭

Shift+G

至檔案尾端

/ 字串

向前搜尋「字串」

? 字串

向後搜尋「字串」

n

重複上一個搜尋 (向前),跟 / ? 有關。

Shift+N

反向重複先前的搜尋 (向後),跟 / ? 有關。

- i

切換搜尋是否區分大小寫,預設為區分大小寫。

- N

切換是否顯示行號

grep 找出符合模式的「行」

grep 語法
grep [選項]... PATTERN(模式) [檔案]...
grep 選項

Pattern selection and interpretation:

-e, --regexp=PATTERN

以 PATTERN 進行匹配

-E, --extended-regexp

PATTERN 為延伸正規表示法 (ERE)

-w, --word-regexp

PATTERN 匹配單詞,如匹配 word,words 則不匹配。

-i, --ignore-case

不區分大小寫

Miscellaneous:

-v, --invert-match

反向匹配,找出不合乎符合模式的「行」。

Output control:

-r, --recursive

遞迴,含目錄內的所有檔案

-n, --line-number

列印行號

-T, --initial-tab

將字元 tab 以 ^I 顯示

-l, --files-with-matches

僅列出檔案內容符合模式的檔名

--include=FILE_PATTERN

僅搜索 GLOB 匹配 FILE_PATTERN 的檔案

Context control:

-B, --before-context=NUM

列出匹配前 NUM 行數

-A, --after-context=NUM

列出匹配後 NUM 行數

grep 匹配多個模式
grep 'Pattern1\|Pattern2' file...
grep -E 'Pattern1|Pattern2' file...
grep 找出目前目錄內符合模式的檔名 (不列示內容)
grep -rl PATTERN
找出 /etc 目錄內的特定文字 (hosts):
grep -rw hosts /etc
grep 如果按語法順序,可不需要 -e 選項,但習慣在把路徑寫在前面,則加入 -e 選項,並把表示法加上單引號比較清楚。
grep /etc -e 'hosts' -rw
找出 /etc 目錄內特定副檔名 (GLOB 匹配) 中的單詞 (w) 文字 (hosts):
grep /etc -e 'hosts' -rw --include=*.allow --include=*.deny
grep /etc -e 'hosts' -rw --include=*.{allow,deny}

cut 擷取部份字元或欄位

cut 命令格式
cut 選項... [檔案]...
cut 選項

-f, --fields=LIST

以定界字元區分出欄位,擷取欄位。

-c, --characters=LIST

擷取字元。

-b, --bytes=LIST

擷取位元組。

-d, --delimiter=DELIM

定界字元,預設為製表字元 (Tab 鍵),只允許一個字元。

--complement

補集參數,將指定的部份刪除,留下剩餘的部份。

--output-delimiter=STRING

將定界字元取代成 STRING

-s, --only-delimited

只列印具有定界字元的行。

-f-c-bLIST 的參數可以是整數、以逗號分隔的多個整數,或者是範圍、以逗號分隔的多個範圍。

範圍可以是以下之一:

n

n 個欄位、字元或位元組。

n-

n 個欄位、字元或位元組到 (該行的) 結尾。

n-m

由第 n 至第 m 個欄位、字元或位元組。

-m

由第一個至第 m 個欄位、字元或位元組。

選項 -c,擷取字元

如擷取前面 6 個字元為 1-6,擷取第 7 個字元至結束如 7-

資料如下
$grep ubuntu /etc/passwd
ubuntu:x:1000:1000::/home/ubuntu:/bin/bash
擷取字元 -c 範例
grep ubuntu /etc/passwd | cut -c 1-6 (1)
grep ubuntu /etc/passwd | cut -c -6 (1)
grep ubuntu /etc/passwd | cut -c 7- (2)
grep ubuntu /etc/passwd | cut -c 1-6 --complement (3)
1 擷取前面 6 個字元
ubuntu
2 擷取第 7 個字元至結束
:x:1000:1000::/home/ubuntu:/bin/bash
3 去掉前面 6 個字元,留下剩餘的部份。
:x:1000:1000::/home/ubuntu:/bin/bash
選項 -d 指定定界字元
以選項 -d 指定定界字元 :,將資料標示出欄位如下:
ubuntu:x:1000:1000::/home/ubuntu:/bin/bash
1     :2:3   :4   ::6           :7
定界字元 -d:,擷取欄位 -f
grep ubuntu /etc/passwd | cut -d : -f 1,6  (1)
grep ubuntu /etc/passwd | cut -d : -f 1,6 --output-delimiter=' ' (2)
1 擷取欄位 1、6。
ubuntu:/home/ubuntu
2 擷取欄位 1、6,將定界字元取代成空白。
ubuntu /home/ubuntu
只列印具有定界字元 (-s) 的行
ls /bin -l | cut -d '>' -s -f 1,2

awk 找出符合欄位的「行」

本文已移至 awk

sed

本文已移至 sed