๐ง fd ๋ช ๋ น์ด ์ฌ์ฉ๋ฒ (find ๋์ ์ด๊ฑฐ ์ฐ์)
fd (์ต์ ์ find)
fd ๋ file system ์์ ํน์ ์ํธ๋ฆฌ๋ฅผ ์ฐพ๋ ๋ช ๋ น์ด๋ก ๊ธฐ์กด find ๋ช ๋ น์ด ๋ณด๋ค ๋ ์ฌ์ฉ์ ์นํ์ ์ด๋ฉฐ ์๋๋ ๊ฑฐ์ 8๋ฐฐ๋ก ๋น ๋ฅด๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ๊ฒ์ํ ํ์ผ๋ค์ ๋ํ ์์ํ ์ถ๋ ฅ์ ์ง์ํ์ฌ ๊ฐ๋ ์ฑ์ ๋์ฌ์ค๋ค.
๋ํ ๊ฒ์ํ ๋ .gitignore ์ ์ง์ ํ ๋๋ ํ ๋ฆฌ๋ ์๋์ผ๋ก ๋ฌด์ํ๋ ๊ธฐ๋ฅ๋ ๋ถ์ด์๋ค. (๋ฌด์ํ์ง ์๋๋ก ํ๋ ์ค์ ๋ ๊ฐ๋ฅ)
fd ๊ธฐ๋ณธ์ ์ผ๋ก ๋์ ๋ฌธ์๋ฅผ ๊ตฌ๋ถํ์ง ์๋๋ค. ๊ฒ์ ํจํด์ ๋๋ฌธ์๊ฐ ํฌํจ ๋ ๊ฒฝ์ฐ fd ๋์ ๋ฌธ์ ๊ตฌ๋ถ ๋ชจ๋๋ก ์๋๋๊ฒ ๋๋ค.
์ด์ฒ๋ผ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ฌ์ฉ์ ํธ์์ฑ์ ์ ํธํ๋ ๋ฐฉ์์ผ๋ก ์๋๋๋ ์ต์ ๋ช ๋ น์ด์ด๋ค.
GitHub - sharkdp/fd: A simple, fast and user-friendly alternative to 'find'
A simple, fast and user-friendly alternative to 'find' - GitHub - sharkdp/fd: A simple, fast and user-friendly alternative to 'find'
github.com
fd ์ค์น
$ apt install fd-find
$ ln -s $(which fdfind) ~/.local/bin/fd
์ฐ๋ถํฌ๋ก ์์ apt ํจํค์ง ์ธ์คํจ๋ฌ๋ก ์ค์นํ๊ฒ ๋๋ฉด, ๋ค๋ฅธ ๋ช ๋ น์ด์ ์ถฉ๋๋๋ฌธ์ fd ๋์ fdfind ์ผ๋ก ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
๋ง์ผ fd์ผ๋ก ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด, ln -s $(which fdfind) ~/.local/bin/fd ๋ช ๋ น์ ํตํด fd์ผ๋ก ์ฌ์ฉ์์ค์ ์ด ๊ฐ๋ฅํ๋ค.
fd ์ฌ์ฉ๋ฒ
$ fd --help # ์ต์
์ ์ฒด ๋ณด๊ธฐ
USAGE:
fd [FLAGS/OPTIONS] [<pattern>] [<path>...]
FLAGS:
-H, --hidden
Include hidden directories and files in the search results (default: hidden files and directories are skipped). Files
and directories are considered to be hidden if their name starts with a `.` sign (dot).
-I, --no-ignore
Show search results from files and directories that would otherwise be ignored by '.gitignore', '.ignore' or
'.fdignore' files.
--no-ignore-vcs
Show search results from files and directories that would otherwise be ignored by '.gitignore' files.
-s, --case-sensitive
Perform a case-sensitive search. By default, fd uses case-insensitive searches, unless the pattern contains an
uppercase character (smart case).
-i, --ignore-case
Perform a case-insensitive search. By default, fd uses case-insensitive searches, unless the pattern contains an
uppercase character (smart case).
-g, --glob
Perform a glob-based search instead of a regular expression search.
--regex
Perform a regular-expression based seach (default). This can be used to override --glob.
-F, --fixed-strings
Treat the pattern as a literal string instead of a regular expression.
-a, --absolute-path
Shows the full path starting from the root as opposed to relative paths.
-L, --follow
By default, fd does not descend into symlinked directories. Using this flag, symbolic links are also traversed.
-p, --full-path
By default, the search pattern is only matched against the filename (or directory name). Using this flag, the pattern
is matched against the full path.
-0, --print0
Separate search results by the null character (instead of newlines). Useful for piping results to 'xargs'.
--show-errors
Enable the display of filesystem errors for situations such as insufficient permissions or dead symlinks.
-h, --help
Prints help information
-V, --version
Prints version information
OPTIONS:
-d, --max-depth <depth>
Limit the directory traversal to a given depth. By default, there is no limit on the search depth.
-t, --type <filetype>...
Filter the search by type (multiple allowable filetypes can be specified):
'f' or 'file': regular files
'd' or 'directory': directories
'l' or 'symlink': symbolic links
'x' or 'executable': executables
'e' or 'empty': empty files or directories
-e, --extension <ext>...
(Additionally) filter search results by their file extension. Multiple allowable file extensions can be specified.
-x, --exec <cmd>
Execute a command for each search result.
All arguments following --exec are taken to be arguments to the command until the argument ';' is encountered.
Each occurrence of the following placeholders is substituted by a path derived from the current search result before
the command is executed:
'{}': path
'{/}': basename
'{//}': parent directory
'{.}': path without file extension
'{/.}': basename without file extension
-X, --exec-batch <cmd>
Execute a command with all search results at once.
All arguments following --exec-batch are taken to be arguments to the command until the argument ';' is encountered.
A single occurence of the following placeholders is authorized and substituted by the paths derived from the search
results before the command is executed:
'{}': path
'{/}': basename
'{//}': parent directory
'{.}': path without file extension
'{/.}': basename without file extension
-E, --exclude <pattern>...
Exclude files/directories that match the given glob pattern. This overrides any other ignore logic. Multiple exclude
patterns can be specified.
--ignore-file <path>...
Add a custom ignore-file in '.gitignore' format. These files have a low precedence.
-c, --color <when>
Declare when to use color for the pattern match output:
'auto': show colors if the output goes to an interactive console (default)
'never': do not use colorized output
'always': always use colorized output
-j, --threads <num>
Set number of threads to use for searching & executing (default: number of available CPU cores)
-S, --size <size>...
Limit results based on the size of files using the format <+-><NUM><UNIT>.
'+': file size must be greater than or equal to this
'-': file size must be less than or equal to this
'NUM': The numeric size (e.g. 500)
'UNIT': The units for NUM. They are not case-sensitive.
Allowed unit values:
'b': bytes
'k': kilobytes
'm': megabytes
'g': gigabytes
't': terabytes
'ki': kibibytes
'mi': mebibytes
'gi': gibibytes
'ti': tebibytes
--changed-within <date|dur>
Filter results based on the file modification time. The argument can be provided as a specific point in time (YYYY-
MM-DD HH:MM:SS) or as a duration (10h, 1d, 35min). '--change-newer-than' can be used as an alias.
Examples:
--changed-within 2weeks
--change-newer-than '2018-10-27 10:00:00'
--changed-before <date|dur>
Filter results based on the file modification time. The argument can be provided as a specific point in time (YYYY-
MM-DD HH:MM:SS) or as a duration (10h, 1d, 35min). '--change-older-than' can be used as an alias.
Examples:
--changed-before '2018-10-27 10:00:00'
--change-older-than 2weeks
--path-separator <separator>
Set the path separator to use when printing file paths. The default is the OS-specific separator ('/' on Unix, '\' on
Windows).
--search-path <search-path>...
Provide paths to search as an alternative to the positional <path> argument. Changes the usage to `fd [FLAGS/OPTIONS]
--search-path <path> --search-path <path2> [<pattern>]`
ARGS:
<pattern>
the search pattern: a regular expression unless '--glob' is used (optional)
<path>...
The directory where the filesystem search is rooted (optional). If omitted, search the current working directory.
fd๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋์๋ฌธ์ ๊ตฌ๋ถ์ ํ์ง ์์ง๋ง PATTERN ์ ๋๋ฌธ์๊ฐ ์์ผ๋ฉด ๋์๋ฌธ์๋ฅผ ๊ตฌ๋ถํ๋ค.
ํ์ผ ๋ฆฌ์คํธ ๋์ด
$ fd # ๊ธฐ๋ณธ์ ์ผ๋ก fd๋ง ์ฐ๋ฉด ls ๊ฐ์ด ํ์ผ๋ค์ ๋์ด
ํ์ผ ๊ฒ์
$ fd <ํ์ผ๋ช
> # ํ์ฌ ๋๋ ํ ๋ฆฌ์์ ํด๋น ํ์ผ๋ช
์ ์ฐพ๋๋ค.
$ fd <ํ์ผ๋ช
> <๊ฒฝ๋ก> # ํด๋น ๊ฒฝ๋ก ๋๋ ํ ๋ฆฌ์์ ํด๋น ํ์ผ๋ช
์ ์ฐพ๋๋ค.
ํ์ผ ํ์ฅ์ ํํฐ๋ง
$ fd -e png # ํ์ผ ํ์ฅ๋ช
ํํฐ๋ง
$ fd -e png 2022-04 # ํ์ผ ํ์ฅ๋ช
ํํฐ๋งํ๋๋ฐ 2022-04 ๋ฌธ์๊ฐ ๋ค์ด๊ฐ ํ์ผ๋ช
๋ง ์์ธ
$ fd -e sh test / # ๋ฃจํธ ๋๋ ํ ๋ฆฌ์์ ์์คํฌ๋ฆฝํธ ํ์ผ์ ๊ฒ์ํ๋๋ฐ ํ์ผ๋ช
์ด๋ฆ์ test๊ฐ ๋ค์ด๊ฐ ํ์ผ๋ง
๊ฒ์ ์ ์ธ (-E)
$ fd -E <๊ฒ์์ ์ ์ธํ ๋๋ ํ ๋ฆฌ๋ช
> # ๋๋ ํ ๋ฆฌ๋ช
์ ์ ์ธํ ํ์ผ ๊ฒ์
์ ๊ท์ ๊ฒ์
fd๋ Rust์ธ์ด๋ก ๊ฐ๋ฐ๋ ๋ช ๋ น์ด ํ๋ก๊ทธ๋จ์ด๊ธฐ ๋๋ฌธ์, ์ ๊ท์ ๋ฌธ๋ฒ์ Rust ์ ๋ฌธ๋ฒ์ ๋ฐ๋ฅธ๋ค.
$ fd '^n.*conf$'
๊ธ๋ก๋ฒ ํจํด ๊ฒ์
-g, --glob ์ต์ ์ ์ฌ์ฉํ๋ฉด ๊ฒฝ๋ก์์ ํจํด๊ณผ ์ผ์นํ๋ ํ์ผ์ ์์ ์๋ค.
$ fd -g '*.png' # ํ์ฌ ๋๋ ํ ๋ฆฌ์์ png ํ์ผ ๊ฒ์
์ฌ์ด์ฆ ๊ฒ์
-S, --size ๋ฅผ ์ฌ์ฉํ๋ฉด ํฌ๊ธฐ๋ฅผ ์ง์ ํด์ ๊ฒ์ํ ์ ์๋ค.
$ fd -S +1M # 1๋ฉ๊ฐ๋ฐ์ดํธ ์ด์์ ํ์ผ๋ง ๊ฒ์
๊ฒ์ ํ์ผ ์ถ๊ฐ ๋ช ๋ น ์คํ (exec)
๊ธฐ์กด find ๋ช ๋ น์ด์๋ -exec ์ต์ ๊ณผ {}, \ ๋ฌธ์๋ฅผ ์ฐ๋ฉด, ๊ฒ์ํ ํ์ผ์ ๋ํ ์ถ๊ฐ ๋ช ๋ น์คํ์ ํ ์ ์์๋ค.
๋น์ฐํ fd์๋ -x ๋ -exec ์ต์ ์ ํตํด ๋ณ๋ ฌ ๋ช ๋ น์ ์คํ ํ ์ ์๋ค.
$ fd -e jpg -x chmod 644 {} # ํ์ฅ์๊ฐ jpg ์ธ ๋ชจ๋ ํ์ผ์ ์ฐพ์ chmod 644 ์ ์คํ
$ fd -e zip -x unzip {} # ํ์ฌ๋๋ ํ ๋ฆฌ์์ zipํ์ผ์ ์ฐพ์ unzipํจ.
fd๋ ํ์ผ ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ๋ค์ด๊ฐ๋ ์ค๊ดํธ {} ์ ๋ํ ์ถ๊ฐ ์ต์ ๋ค์ ์ ๊ณตํ๋ค.
- {}: ๋ฐ๊ฒฌ ๋ ํ์ผ์ ์ ์ฒด ํ์ผ ๊ฒฝ๋ก ๋ฐ ์ด๋ฆ
- {/}: ์ฐพ์ ํ์ผ์ ํ์ผ ์ด๋ฆ
- {//}: ์ฐพ์ ํ์ผ์ด ํฌํจ ๋ ๋๋ ํ ๋ฆฌ
- {/.}: ์ฐพ์ ํ์ผ์ ํ์ฅ์์์ด ํ์ผ ์ด๋ฆ
ignore ํ์ผ๋ก ๊ฒ์ ์ ์ธ
fd ๋ ๊ฒ์ํ์ง ์์ ํจํด๋ค์ $HOME/.fdignore ํ์ผ์ ๋ฑ๋กํด ๋๋ฉด ์ด ํ์ผ๋ค์ ๊ฒ์์ ์๋์ผ๋ก ์ ์ธ๋๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก .gitignore ์ ๋ฑ๋ก๋ ํจํด๋ค์ ์ฐพ์ง ์๊ฒ ๋๋ค.
๋ฐ๋ผ์ ๋ค์๊ณผ ๊ฐ์ด .fdignore ํ์ผ์ ๋ฑ๋ก๋์ด ์๋ค๋ฉด ๊ฒ์์ .class ์ .xml ์ด ์๋ ํ์ผ๋ง ์ถ๋ ฅ๋๊ฒ ๋๋ค.
*.class
*.xml
-I, --no-ignore ์ต์ ๋ฅผ ์ฌ์ฉํ๋ฉด .gitignore ๋ .fdignore ์ ๋ฑ๋ก๋ ํ์ผ ํจํด๋ ๊ฒ์ํ๋ค.
๋ณ๊ฒฝ ์๊ฐ์ผ๋ก ๊ฒ์
--change-newer-than <๊ธฐ๊ฐ>๋ฅผ ์ฌ์ฉํ๋ฉด ๋ณ๊ฒฝ์ผ์ด ํน์ ์ผ ์ดํ์ธ ํ์ผ์ ์ฐพ์ ์ ์๋ค.
๊ธฐ์กด find ๋ช ๋ น์ด์ mtime/mmin ์ต์ ์ญํ ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
๊ธฐ๊ฐ์๋ 1weeks ๋ 3months ๊ฐ์ด ์ ์ด์ฃผ๋ฉด ๋๋ค.
$ fd --change-newer-than 7days # ํ์ฌ์ผ ๊ธฐ์ค ๋ณ๊ฒฝ์ผ์ด 7์ผ ์ดํ์ ๋ณ๊ฒฝ๋ ํ์ผ์ ๊ฒ์
$ fd . --change-newer-than '2021-08-23 10:00:00' /tmp # /tmp ๋๋ ํ ๋ฆฌ์์ 2021-08-23์ผ 10์ ์ดํ์ ๋ณ๊ฒฝ๋ ํ์ผ์ ๊ฒ์
๋ฐ๋๋ก ๋ณ๊ฒฝ์ผ์ด ํน์ ์ผ ์ด์ ์ธ ํ์ผ์ ์ฐพ์ ๊ฒฝ์ฐ --change-older-than <๊ธฐ๊ฐ> ์ ์ฌ์ฉํ๋ฉด ๋๋ค.
$ fd --change-older-than 7days -l # ํ์ฌ์ผ ๊ธฐ์ค ๋ณ๊ฒฝ์ผ์ด 7์ผ ์ด์ ์ธ ํ์ผ๋ค์ ๊ฒ์
2๊ฐ์ง ์ต์ ์ ๊ฐ์ด ์ฐ๋ฉด BETWEEN ์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ค.
$ fd . --change-newer-than '2021-08-24 04:30:00' --change-older-than '2021-08-25 00:00:00' /tmp # /tmp ์๋์์ ๋ณ๊ฒฝ์ผ์ด ํน์ ๊ธฐ๊ฐ ์ฌ์ด์ธ ํ์ผ๋ค์ ์ ์ฒด ๊ฒ์
์ด์ธ์ ๋ชจ๋ ๋ฆฌ๋ ์ค ๋ช ๋ น์ด ๋ชจ์
[Modern Linux] ๐ง ๋ชจ๋ ๋ฆฌ๋ ์ค - ์ต์ ์ ๋ฆฌ๋ ์ค ๋ช ๋ น์ด ๋ชจ์
๋ชจ๋ ๋ฆฌ๋ ์ค/์ ๋์ค ๋ช ๋ น์ด ๋๋ถ๋ถ์ ๋ฆฌ๋ ์ค ๊ฐ์๋ ์์ ์์๋ ์ด์ฐฝ๊ธฐ๋ถํฐ ์๋ ์ ํต์ ์ธ CLI ๋ช ๋ น์ด(ls, cd, pwd, cat, cp, mv, rm, mkdir, ...๋ฑ) ์์ฃผ๋ก ์๋ ค์ค๋ค. ๊ทธ๋ฌ๋ ์ด ์ค๋๋ ๋ช ๋ น์ด๋ค์ ์์ฑ๋
inpa.tistory.com