csvls is a command-line utility that lists files and directories in CSV format.
It provides flexible options to display file metadata such as type, owner, group, size, permissions, timestamps, and more.
Clone the repository and build with make:
git clone -b main --single-branch https://github.com/ISOnRM/csvls.git
cd csvls
make -j
sudo make install
Command:
csvls -gOst -SOutput:
type,owner,group,size,path
D,mark,mark,4.0K,.
F,mark,mark,0B,./IAmAFile
P,mark,mark,0B,./IAmAFifo
L,mark,mark,9B,./IAmALink
D,mark,mark,4.0K,./IAmADircsvls -hUsage:
csvls [options] <targets>...
Description:
Targets are given without a leading "-" and must be existing directories or files.
Multiple targets can be passed.
Options:
-h, --help Show this help message and exit.
If combined with other options, they will be ignored.
-d, --show-dev Display device ID.
-I, --show-inode Display inode number.
-t, --show-type Display file type.
-p, --show-perms Display file permissions.
-n, --show-nlinks Display number of hard links.
-O, --show-owner Display owner’s user ID.
-g, --show-group Display group ID.
-s, --show-size Display size in bytes.
-b, --show-blocks Display number of blocks.
-a, --show-access-time Display last access time.
-m, --show-mod-time Display last modification time.
-M, --show-meta-mod-time Display metadata change time.
-N, --name Display entry name.
-c, --canonical Display canonical path.
-S, --sort Sort output by selected columns.
-r, --recursive Enable recursive directory traversal.
csvls -t . ThisIsADir # --show-typetype,path
D,.
F,./ThisIsAFile
L,./ThisIsALink
D,./ThisIsADir
D,ThisIsADir
F,ThisIsADir/FileOne
F,ThisIsADir/FileThree
F,ThisIsADir/FileTwocsvls -sOg ThisIsAFile # --show-size --show-owner --show-groupsize,owner,group,path
0B,mark,users,ThisIsAFilecsvls -d # --show-devdevice,path
66311,.
66311,./ThisIsAFile
66311,./ThisIsALink
66311,./ThisIsADircsvls -I # --show-inodeinode,path
10394808,.
10394993,./ThisIsAFile
10395323,./ThisIsALink
10395317,./ThisIsADircsvls -p # --show-permspermissions,path
rwxr-xr-x,.
rw-r--r--,./ThisIsAFile
rwxrwxrwx,./ThisIsALink
rwxr-xr-x,./ThisIsADircsvls -n # --show-nlinkslinks,path
3,.
1,./ThisIsAFile
1,./ThisIsALink
2,./ThisIsADircsvls -O # --show-ownerowner,path
mark,.
mark,./ThisIsAFile
mark,./ThisIsALink
mark,./ThisIsADircsvls -g # --show-groupgroup,path
users,.
users,./ThisIsAFile
users,./ThisIsALink
users,./ThisIsADircsvls -s # --show-sizesize,path
4.0K,.
0B,./ThisIsAFile
12B,./ThisIsALink
4.0K,./ThisIsADircsvls -b # --show-blocksblocks,path
8,.
0,./ThisIsAFile
0,./ThisIsALink
8,./ThisIsADircsvls -a # --show-access-timeaccess_time,path
02-08-2025 12:50:22,.
02-08-2025 12:49:29,./ThisIsAFile
02-08-2025 12:50:22,./ThisIsALink
02-08-2025 12:49:34,./ThisIsADircsvls -m # --show-mod-timemod_time,path
02-08-2025 12:50:21,.
02-08-2025 12:49:29,./ThisIsAFile
02-08-2025 12:50:21,./ThisIsALink
02-08-2025 12:49:34,./ThisIsADircsvls -M # --show-meta-mod-timemeta_mod_time,path
02-08-2025 12:50:21,.
02-08-2025 12:49:29,./ThisIsAFile
02-08-2025 12:50:21,./ThisIsALink
02-08-2025 12:49:34,./ThisIsADircsvls -N # --namepath
.
./ThisIsAFile
./ThisIsALink
./ThisIsADircsvls -c # --canonicalpath
/home/mark/csvls_showcase/test
/home/mark/csvls_showcase/test/ThisIsAFile
/home/mark/csvls_showcase/script.py
/home/mark/csvls_showcase/test/ThisIsADircsvls -r # --recursivepath
.
./ThisIsAFile
./ThisIsALink
./ThisIsADir
./ThisIsADir/FileOne
./ThisIsADir/FileThree
./ThisIsADir/FileTwocsvls -sgOt . # --show-size --show-group --show-owner --show-typesize,group,owner,type,path
4.0K,users,mark,D,.
0B,users,mark,F,./ThisIsAFile
12B,users,mark,L,./ThisIsALink
4.0K,users,mark,D,./ThisIsADircsvls -sgOt -S . # --show-size --show-group --show-owner --show-type --sorttype,owner,group,size,path
D,mark,users,4.0K,.
F,mark,users,0B,./ThisIsAFile
L,mark,users,12B,./ThisIsALink
D,mark,users,4.0K,./ThisIsADir-
No heavy use of
std::filesystem: Most functions instd::filesystemcallstatmultiple times for different attributes. Instead,csvlscallsstatonce per entry and extracts all attributes directly. -
Source structure (
src/):aliases_and_concepts/→ Aliases and conceptscli/→ Argument parser classchecker/→ Functions that validate parsed options and argumentsassembler/→ Class that collects entries and callsstatcsv_writer/→ Class that writes CSV output to stdout
- An ability to see raw (octal) entry's permissions
- An ability to see size in bytes instead of human readable units
- An ability to see raw time (Any st_*time member)
I learned the hard way that if you don't sit down, think, and outline a project's structure on paper beforehand, actual coding becomes a Sisyphean task. This would have been ten times easier if I had done so, but unfortunately I did not. This is my first ever C++ project of a somewhat decent size. In the process I learned that I love C a lot more.
This project is licensed under the MIT License. See LICENSE for details.