[LINUX] Follow the file hierarchy with fts

A note on how to navigate the file hierarchy using fts.

sample

Create a sample program that scans the directory given by the argument and outputs the size and pathname.

sample.cpp


#include <cstdio>
#include <fts.h>
#include <sys/stat.h>

int main(int argc, char** argv)
{
    if (argc != 2) {
        std::fprintf(stderr, "Usage: %s <dir>\n", argv[0]);
        return -1;
    }

    char* const paths[] = {argv[1], nullptr};

    FTS* fts = fts_open(paths, 0, nullptr);
    if (fts == nullptr) {
        std::fprintf(stderr, "open failed.\n");
        return -1;
    }

    FTSENT* ent = nullptr;
    while ((ent = fts_read(fts)) != nullptr) {
        std::printf("%-5lu %s\n", ent->fts_statp->st_size, ent->fts_path);
    }

    if (fts_close(fts) != 0) {
        std::fprintf(stderr, "close failed.\n");
        return -1;
    }

    return 0;
}

The directory and file size paths can be output recursively.

$ g++ -std=c++14 sample.cpp -o sample
$ ./sample testdir
4096  testdir
4096  testdir/subdir
114   testdir/subdir/fff.txt
110   testdir/subdir/eee.txt
49    testdir/subdir/ddd.txt
4096  testdir/subdir
64    testdir/bbb.txt
48    testdir/aaa.txt
8     testdir/ccc.txt
4096  testdir

Change file hierarchy scan order

By giving a function pointer to fts_open, it seems possible to change the order in which the file hierarchy is scanned.

$ man fts
... 
       FTS *fts_open(char * const *path_argv, int options,
                     int (*compar)(const FTSENT **, const FTSENT **));
... 
       The argument compar() specifies a user-defined function which may be used to order the traversal of the hierarchy.  
       It takes two pointers to pointers to FTSENT structures as arguments and should return a negative value, zero, or a positive value to indicate if the file referenced by its first argument comes before, in any order with respect to, or after, the file referenced by its second argument.
...

So, modify it to give a function pointer so that the size is output in ascending order, and execute it again.

sample2.cpp


#include <cstdio>
#include <fts.h>
#include <sys/stat.h>

static int compar(const FTSENT** rhs, const FTSENT** lhs)
{
    const FTSENT* r = *rhs;
    const FTSENT* l = *lhs;

    return (r->fts_statp->st_size - l->fts_statp->st_size);
}

int main(int argc, char** argv)
{
    if (argc != 2) {
        std::fprintf(stderr, "Usage: %s <dir>\n", argv[0]);
        return -1;
    }

    char* const paths[] = {argv[1], nullptr};

    FTS* fts = fts_open(paths, 0, compar);
    if (fts == nullptr) {
        std::fprintf(stderr, "open failed.\n");
        return -1;
    }

    FTSENT* ent = nullptr;
    while ((ent = fts_read(fts)) != nullptr) {
        std::printf("%-5lu %s\n", ent->fts_statp->st_size, ent->fts_path);
    }

    if (fts_close(fts) != 0) {
        std::fprintf(stderr, "close failed.\n");
        return -1;
    }

    return 0;
}

Files in the directory are now output in ascending order of size.

$ g++ -std=c++14 sample2.cpp -o sample2
$ ./sample2 testdir/
4096  testdir/
8     testdir/ccc.txt
48    testdir/aaa.txt
64    testdir/bbb.txt
4096  testdir/subdir
49    testdir/subdir/ddd.txt
110   testdir/subdir/eee.txt
114   testdir/subdir/fff.txt
4096  testdir/subdir
4096  testdir/

Recommended Posts

Follow the file hierarchy with fts
Extract the xz file with python
Download the file deployed with appcfg.py
Open the file with the default app
Check the existence of the file with python
Let's read the RINEX file with Python ①
Try rewriting the file with the less command
Check the file size with du -sh *
Download the file with PHP [Under construction]
Adjust file permissions with the Linux command chmod
Follow the AR marker with a 2-axis servo
Save the object to a file with pickle
Load the TensorFlow model file .pb with readNetFromTensorflow ().
Convert the character code of the file with Python3
File operations with open — "../"
I tried to touch the CSV file with Python
File upload with django
Follow the communication flow of Docker's bridge connection with nftables
[Python] Read the csv file and display the figure with matplotlib
Access the file with a relative path from the execution script.
Read the GRIB2 file of the Japan Meteorological Agency with pygrib
Read the VTK file and display the color map with jupyter.
I tried to divide the file into folders with Python
Try to decipher the garbled attachment file name with Python
Download the file in Python
Insert the debugger with nose
Kill the process with sudo kill -9
Draw netCDF file with python
Fast file transfer with fabric
Unzip the internet zip file
Guess the password with klee
File access under the directory
Bidirectional file transfer with Pythonista 3
gethostbyaddr () communicates with the outside
scraping the Nikkei 225 with playwright-python
Check the code with flake8
Calibrate the model with PyCaret
Call the API with python3.
File upload with Flask + jQuery
Download csv file with python
Create xlsx file with XlsxWriter
Can you delete the file?
Process the contents of the file in order with a shell script
How to make a command to read the configuration file with pyramid
Format the CSV file of "National Holiday" of the Cabinet Office with pandas
When I run the exe file with pyinstaller, my PC crashes.
Read a file in Python with a relative path from the program
The idea of feeding the config file with a python file instead of yaml
When doing sam build with AWS Lambda Layers, the file hierarchy changes and an import error occurs.