开发者发布用 Bash 编写的文件排序工具 Tmv
来源标题:Show HN: Tmv – File sorting utility written in Bash
开发者在 Hacker News 的 Show HN 板块发布了一款名为 Tmv 的文件排序工具,完全用 Bash 编写。该工具已在 Show HN 上公开,供用户了解和使用。
以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。
About the project
tmv ("timer mv") is a file sorter written purely in Bash. It moves files into named folders based on presets or glob patterns, either on demand from the command line or automatically through a systemd user timer.
Repository layout
tmv/ ├── install.sh # installer (copy or symlink, systemd units, example env) ├── bin/ │ └── tmv # entry point: argument parsing, dispatch ├── lib/ │ ├── presets.sh # preset -> extensions map, selector -> globs │ ├── sorter.sh # core logic: tmv_move_matching │ └── validate.sh # env file parser and rule checks (tmv -t) ├── systemd/ │ ├── tmv.service # oneshot service: validate, then sort │ └── tmv.timer # runs the service every 15 minutes ├── examples/ │ └── tmv.env # example rules file ├── tests/ │ └── run.sh # manual test script (works in /tmp/t) ├── DESIGN.md # design decisions, edge cases, roadmap └── LICENSE
How it works
Both modes use the same core function, tmv_move_matching <dir> <selector> <dest_name>: one logic, two entry points.
Path Purpose
~/.local/share/tmv/ program files (bin/, lib/)
~/.local/bin/tmv symlink to the entry point
~/.config/tmv/tmv.env your rules
~/.config/systemd/user/tmv.{service,timer} systemd user units
Everything is installed per user. No root is needed.
Bash 4+ (associative arrays), GNU find, flock, readlink, and systemctl (systemd) for timer mode.
git clone https://github.com/SamerKolasevic29/tmv.git cd tmv ./install.sh
Then:
1. edit your rules
$EDITOR ~/.config/tmv/tmv.env
2. validate them
tmv -t
3. see what would happen, without moving anything
tmv -n --env
4. start the timer
systemctl --user enable --now tmv.timer
Or do steps 2 and 4 at once: ./install.sh --enable validates the env and enables the timer only if the validation passes.
The timer does not start automatically after a plain install, because the example env sorts ~/Downloads and you should review the rules first.
Option Description
(none) copy the program, install units and the example env
--enable also validate the env, then enable and start tmv.timer
--link development mode: symlink ~/.local/bin/tmv to the repo
--uninstall remove tmv and the units (keeps ~/.config/tmv)
Useful commands
systemctl --user list-timers tmv.timer # next run systemctl --user start tmv.service # run now journalctl --user -u tmv -e # logs loginctl enable-linger "$USER" # keep the timer running without an active session
Changing the interval
The default is every 15 minutes (OnCalendar=*:0/15). To override it without touching the repo:
systemctl --user edit tmv.timer
[Timer] OnCalendar= OnCalendar=hourly
The empty OnCalendar= line is required, otherwise the new value is added to the old one.
CLI usage
tmv [options] <selector> <folder> [<selector> <folder> ...] tmv [options] --env [file] tmv -t [file]
tmv --video-files Videos tmv ".mp3" Music tmv --video-files Videos --music-files Music ".docx" Word_documents tmv -n --images-files Pictures # dry run
Always quote globs ("*.mp3"), otherwise the shell expands them before tmv sees them.
Flag Description
-n, --dry-run print what would be moved, change nothing
--min-age N skip files modified in the last N minutes (default 1)
-t, --test [file] validate an env file (default ~/.config/tmv/tmv.env)
--env [file] sort TARGET_DIR using an env file
-h, --help show help
Selectors
A selector is either a preset or a glob (case-insensitive, no / allowed).
In env files the leading -- is optional and so is -files (video, --video-files and video-files all work).
TARGET_DIR="$HOME/Downloads"
TARGET_FILES="--video-files" DIR_NAME="Videos"
TARGET_FILES="*.iso" DIR_NAME="ISO"
tmv -t checks three rules:
Additionally: TARGET_DIR must exist and be writable, presets must be known, and DIR_NAME must be a plain name (no /, not . or ..). Blank lines and # comments are ignored. Only a leading ~ or $HOME is expanded in values.
The env file is parsed, never sourced, so it cannot execute code and repeated keys do not overwrite each other. Currently one TARGET_DIR per file is supported.
Never overwrites: name collisions get a numeric suffix (film.mp4, film_1.mp4, film_2.mp4).
Not recursive: only files directly inside the target directory are touched; folders and symlinks are left alone.
Downloads are safe: files modified within the last minute and temporary files (.part, .crdownload, .tmp, .download, .partial) are skipped.
Hidden files are ignored unless a glob explicitly starts with ..
First rule wins if a file matches several rules.
All-or-nothing validation: CLI pairs and env files are fully validated before the first file is moved.
No overlapping runs: a lock (flock) prevents two instances from running at once.
Missed runs are caught up (Persistent=true) when the machine was off.
Exit codes
Code Meaning
0 success
1 invalid env file, or at least one move failed
2 invalid command-line usage
License
Released under the MIT License.
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。