# WinDirStat-Export `wdsexport` scans a directory tree on Linux (or macOS) and writes a [WinDirStat](https://windirstat.net) 2.x **saved-results CSV**. Copy it to a Windows machine and open it with **File → Open saved results** to browse the remote disk with WinDirStat's treemap. Single Python file, standard library only, Python 3.8+. ## Install ```sh git clone https://gitea.lucaswinther.info/lucasw89/WinDirStat-Export.git cd WinDirStat-Export ./install.sh # -> ~/.local/bin/wdsexport # or: ./install.sh /usr/local (with sudo) # or: pipx install . ``` ## Usage ```sh wdsexport # scan /, write ./-root.csv wdsexport / --zip # also write a .zip (CSVs compress ~15x) sudo wdsexport / # include root-only dirs (/var/lib/docker, ...) wdsexport ~/projects -o proj.csv # scan one directory wdsexport / --exclude /home/me/vms --lang da wdsexport / -o - | gzip > scan.csv.gz ``` | Argument | Default | Meaning | |---|---|---| | `PATH` | `/` | Directory to scan | | `-o, --output FILE` | `./.csv` | Output CSV; `-` writes to stdout | | `--name NAME` | `-` | Root folder name shown in WinDirStat | | `--exclude DIR` | — | Skip a directory (repeatable) | | `--zip` | off | Also write `.zip` | | `--lang CODE` | `en` | Column-name language (see below) | | `--cross-fs` | off | Descend into other mounted filesystems (default stays on one, like `du -x`) | | `-q, --quiet` | off | No progress output | ### `--lang` must match WinDirStat's UI language WinDirStat identifies CSV columns by their *localized* header names. If your WinDirStat runs in Danish, export with `--lang da`; otherwise the file is rejected. Supported: ar, cs, da, de, en, es, et, fi, fr, hi, hu, it, ja, ko, nb, nl, pl, pt, ru, sl, sv, tr, uk, zh, zh-HK. ## What gets recorded - **Logical size** = file length; **physical size** = allocated blocks (`st_blocks × 512`), so sparse files and filesystem overhead show correctly. - Hard-linked files are counted once (first path seen). - Symlinks are recorded as small files and never followed. - Dotfiles get the Hidden attribute, so enable *show hidden files* in WinDirStat. - Directories that can't be read are marked *partial* (WinDirStat shows them as incomplete). Run with `sudo` to include them. - Characters WinDirStat's CSV parser can't handle in names are replaced: `\` → `_`, `"` → `'`, newlines → space. Invalid UTF-8 becomes `�`. - The tool skips its own output and temporary files when they sit inside the scanned tree. Disk space: the scan writes a temporary file about the size of the final CSV next to the output (in `$TMPDIR` for `-o -`). Roughly 200 bytes per file, so 8 million files ≈ 1.5 GB CSV, ≈ 100 MB zipped. ## How it works The format follows WinDirStat's own loader ([`CsvLoader.cpp`](https://github.com/windirstat/windirstat/blob/master/windirstat/CsvLoader.cpp)): rows must list each parent before its children, paths use `\` separators, and folder rows carry subtree totals. `wdsexport` writes rows in post-order (when folder totals are known) to a temp file and then copies it out reversed, which gives a parent-first order without holding the tree in memory. ## Development ```sh python3 -m unittest discover -s tests python3 tools/gen_langs.py # refresh column names from WinDirStat's language files ``` ## License MIT