最後更新: 2024-09-27
目錄
- 常用 Opts
- Size
- Type
- Permission
- Depth
- regex
- path
- Symbolic
- Action - prune
- Action - exec
- find 與 xargs
- A pipe "|" in linux 's find -exec command
- 應用
介紹
The "find" searches the directory tree rooted at each given starting-point
evaluating the given expression from left to right
If no starting-point is specified, `.' is assumed
Note that the pattern match test applies to the whole file name, starting from one of the start points named
常用 Opts
Time
-mtime
Unit # n x 24 小時
- +n # for greater than
- -n # for less than n
- n # n 當天 24 小時內的 file
i.e.
# n*24 hours ago
-mtime n
# file less than 24 hours ago
find $HOME -mtime 0
-mmin
File's data was last modified n minutes ago.
i.e.
find $LockFile -mmin +2
P.S.
雖然 ls 時是看不到秒數, 但秒數依然計算在內, 所以 17:50 未必出現 17:48 的 Dir
-newer file
File was modified more recently than file.
-newerXY reference
i.e.
-newermt "2021-08-04"
- m The modification time of the file reference
- t "reference" is interpreted directly as a time
Time specifications are interpreted as for the argument to the -d option of GNU `date`
(i.e. "2004-02-29 16:21:42")
i.e. 有某段時間修改過的 file
# -ls list current file in ls -dils format on standard output.
[方式1]
find . -type f -newermt "2021-08-04 18:40" ! -newermt "2021-08-04 18:55" -ls
Or
[方式2]
touch --date="2021-08-04 18:40" start
touch --date="2021-08-04 18:55" stop
find / -newer start \! -newer stop -ls
user(-uid/-usr)
-uid n
-user <uname>
group(-gid/-group)
-gid n
-group gname
filename(-name/-iname)
-name pattern # case sensitive
-iname pattern # case insensitive
Base of file name (the path with the leading directories removed) matches shell pattern.
=> "-name a/b" will never match anything (use -path instead)
pattern
- "*", "?", "[]" match a `.' at the start of the basename
- Braces("{}") are not recognised as being special
e.g.
touch {1,12,123,.12}.txt
find . -name "???.txt" # Output ./.12.txt ./123.txt
Notes
* To enclose the pattern in quotes in order to protect it from expansion by the shell.
另見 -regex
Size
-size n[cwbkMG]
units
- 'b' for 512-byte blocks
- 'c' for bytes
- 'k' for Kilobytes
- 'M' for Megabytes
- 'G' for Gigabytes
# 找出大過 10M 的東西
find . -size +10M
Type
-type f | d | l | ...
Permission
-perm mode
- u = user
- g = group
- o = other
- a = all
find . -perm NNN
664 <-- permission 是 644
-664 <-- 最少有這些 bit 的意思 (This will match a file which has mode 0777)
All of the permission bits mode are set for the file.
[without regard to the presence of any extra permission bits]
/222 <-- Search for files which are writable by somebody
Any of the permission bits mode are set for the file.
touch 600 060 006 066 660 606 666 # 7 Files
chmod 600 600; chmod 060 060; chmod 006 006
chmod 066 066; chmod 660 660; chmod 606 606; chmod 666 666
find . -perm /220 # 不中 006
find . -perm /202 # 不中 060
All three of these commands do the same thing
- find . -perm /220
- find . -perm /u=w,g=w
- find . -perm /u+w,g+w
"!"
find . \! -user foo -print # 找出 other 沒有 read 的 file / folder
find . ! -perm -o=r # 這 cmd 可能會漏了沒有 "x" 的 Folder
find . -type f ! -perm -o=r
find . -type d ! -perm -o=rx
# To find all SGID files:
find / -xdev -type f -perm +g=s -print
# To find all SUID files
find / -xdev -type f -perm +u=s -print
Depth
-maxdepth levels
-mindepth levels
regex
# File name matches regular expression pattern.
find /proc -maxdepth 1 -regex '/proc/[0-9]+'
path
-path pattern
File name matches shell pattern pattern (do not treat `/' or `.' specially)
i.e.
# 會中 "./src/misc"
find . -path "./sr*sc"
# never match anything
find bar -path /foo/bar/myfile -print
* 在 bar 之下的 path 會是 bar/123, bar/234 之類
# Exclude top level directory (首個出現的結果: ".")
find . ! -path . -type d -mtime -90 -print
# 應用情況: 以下指令把所有 Folder copy 了, 而不是 90 日內的 Folder
find . -type d -mtime -90 -exec cp -a {} /data/apps/data/tmp \;
. ./43263 ./43224 ...
Note: 同效
find . -mindepth 1 -type d -mtime -90 -print
Symbolic
-L Follow symbolic links
# fine link file only
find . -maxdepth 1 -type l
Action - prune
它是 ACTIONS 來, 當中了 "條件" 後就會 ignore 之後的 tree
i.e. 在當前目錄下找出 90 內更新過名叫 tmp 的頂層 Folder
find . -type d -mtime -90 -path "*/tmp*" -prune
Action - exec
find . -type f -exec file '{}' \;
remark
'{}' 與 \; 之間要有空格
find 與 xargs
find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f
解釋
find 的 -print0
# print the full file name on the stout followed by a null character
(instead of the newline character that -print uses)
xargs 的 -0
# Input items are terminated by a null character instead of by whitespace
A pipe "|" in linux 's find -exec command
# top level shell to perform the piping
# 缺點是不知每目錄內郵件數量
find . -type d -name cur -exec ls -1 "{}" \; | wc -l
# execute via sh
* 注意: This "{}" in your first command may even lead to code injection.
* 不建議用, 檔名有空格都已經出事.
(literally named " & rm -rf ~ & : ".txt)
find . -type d -name cur -exec sh -c 'echo {}; ls -1 {} | wc -l' \;
應用
1) 將 mail 按年歸類
ie. 2021 年
su vmail -s /bin/bash touch --date="2021-01-01 00:00" startref touch --date="2022-01-01 00:00" stopref mkdir -p .2021/cur ls -d .2021/cur find cur -type f -newer startref \! -newer stopref -exec ls -l '{}' .2021/cur \; find cur -type f -newer startref \! -newer stopref -exec mv -i '{}' .2021/cur \;