• utility to count files matching a pattern

    From =?UTF-8?Q?Henrik_Paludan=2DM=C3=B8r@21:1/5 to All on Mon Feb 22 07:03:59 2021
    I have need of a utility that will count files matching a disk file name pattern.
    Does any of you know a smart thingy?

    //Henrik P

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JShepherd@21:1/5 to All on Mon Feb 22 15:48:00 2021
    In article <3a68f726-ce63-40e5-bbd8-b3c4f85126f6n@googlegroups.com>, kilgasto@gmail.com says...

    I have need of a utility that will count files matching a disk file name pattern
    .
    Does any of you know a smart thingy?

    //Henrik P

    This gets you most of the way there


    #pragma fieldalign shared2 FILEINFO_DEF
    typedef struct FILEINFO_DEF
    {
    int64_t modtime;
    int64_t createts;
    int64_t lastopents;
    int64_t eof;
    unsigned short priext;
    unsigned short secext;
    short maxext;
    short extalloc;
    short userid;
    short filecode;
    short filetype;
    short reclen;
    short blocklen;
    short progid;
    short clearonpurge;
    char security[4];
    short licensed;
    short audited;
    short createoptions;
    short fileisopen;
    short crashopen;
    short broken;
    short corrupt;
    short numpartitions;
    short ossfile;
    short xpartition;
    short securitytype;
    short format;
    short numaltkeys;
    short sqlprogram;
    short sqlvalid;
    struct
    {
    short devtype;
    short subtype;
    short objecttype;
    short filetype;
    short filecode;
    } typeinfo;
    short filename_len;
    char filename[48];
    } FILEINFO_DEF;

    struct
    {
    int64_t bytes;
    int64_t files;
    int64_t files_scanned;
    int64_t filesets;
    } total;


    /*-------------------------------------------------------------------------*
    * *
    *-------------------------------------------------------------------------*/ short FI_listfiles(char *filename, short filename_len)
    {
    short erc = 0;
    short search_id = 0;
    struct
    {
    short devtype;
    short subtype;
    short objtype;
    short filetype;
    short filecode;
    } typeinfo;

    FILEINFO_DEF fi;

    if (detail)
    {
    sprintf(message, "Processing pattern %s", filename);
    printmessage(message);
    }

    erc = FILENAME_FINDSTART_(&search_id,
    filename,filename_len,
    -1, /* resolve vol to filename */
    3, /* disc devices */
    -1, /* devicesubtype */
    0, /* options */
    filename, 0);
    if (erc)
    {
    sprintf(message, "FILENAME_FINDSTART_ error %d on %s",
    erc, filename);
    printmessage(message);
    return(0);
    }

    while (erc != 1)
    {
    erc = FILENAME_FINDNEXT_(search_id,
    filename, 48, &filename_len,
    (short *)&typeinfo,
    0);
    if (erc)
    {
    break;
    }

    filename[filename_len] = 0;

    memset(&fi, 0, sizeof(fi));
    erc = FI_getfileinfo(filename,filename_len, &fi);
    if (erc == 0)
    {
    total.files_scanned = total.files_scanned + 1;
    process_file(&fi);
    }
    } /* while */

    FILENAME_FINDFINISH_(search_id);

    return(0);
    } /* FI_listfiles */

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Randall@21:1/5 to JShepherd on Mon Feb 22 10:43:54 2021
    On Monday, February 22, 2021 at 10:48:02 a.m. UTC-5, JShepherd wrote:
    In article <3a68f726-ce63-40e5...@googlegroups.com>,
    kilg...@gmail.com says...

    I have need of a utility that will count files matching a disk file name pattern
    .
    Does any of you know a smart thingy?

    //Henrik P
    This gets you most of the way there


    #pragma fieldalign shared2 FILEINFO_DEF
    typedef struct FILEINFO_DEF
    {
    int64_t modtime;
    int64_t createts;
    int64_t lastopents;
    int64_t eof;
    unsigned short priext;
    unsigned short secext;
    short maxext;
    short extalloc;
    short userid;
    short filecode;
    short filetype;
    short reclen;
    short blocklen;
    short progid;
    short clearonpurge;
    char security[4];
    short licensed;
    short audited;
    short createoptions;
    short fileisopen;
    short crashopen;
    short broken;
    short corrupt;
    short numpartitions;
    short ossfile;
    short xpartition;
    short securitytype;
    short format;
    short numaltkeys;
    short sqlprogram;
    short sqlvalid;
    struct
    {
    short devtype;
    short subtype;
    short objecttype;
    short filetype;
    short filecode;
    } typeinfo;
    short filename_len;
    char filename[48];
    } FILEINFO_DEF;

    struct
    {
    int64_t bytes;
    int64_t files;
    int64_t files_scanned;
    int64_t filesets;
    } total;


    /*-------------------------------------------------------------------------* * * *-------------------------------------------------------------------------*/ short FI_listfiles(char *filename, short filename_len)
    {
    short erc = 0;
    short search_id = 0;
    struct
    {
    short devtype;
    short subtype;
    short objtype;
    short filetype;
    short filecode;
    } typeinfo;

    FILEINFO_DEF fi;

    if (detail)
    {
    sprintf(message, "Processing pattern %s", filename);
    printmessage(message);
    }

    erc = FILENAME_FINDSTART_(&search_id,
    filename,filename_len,
    -1, /* resolve vol to filename */
    3, /* disc devices */
    -1, /* devicesubtype */
    0, /* options */
    filename, 0);
    if (erc)
    {
    sprintf(message, "FILENAME_FINDSTART_ error %d on %s",
    erc, filename);
    printmessage(message);
    return(0);
    }

    while (erc != 1)
    {
    erc = FILENAME_FINDNEXT_(search_id,
    filename, 48, &filename_len,
    (short *)&typeinfo,
    0);
    if (erc)
    {
    break;
    }

    filename[filename_len] = 0;

    memset(&fi, 0, sizeof(fi));
    erc = FI_getfileinfo(filename,filename_len, &fi);
    if (erc == 0)
    {
    total.files_scanned = total.files_scanned + 1;
    process_file(&fi);
    }
    } /* while */

    FILENAME_FINDFINISH_(search_id);

    return(0);
    } /* FI_listfiles */

    This can be done in TACL as well using the #FILENAMES builtin. The TACL Programming Guide describes how to use #FILENAMES, with an example showing:

    #SET prevname [#FILENAMES /MAXIMUM 1, PREVIOUS [prevname]/ [filetemplate]]

    Basically, you count the number of iterations until prevname is blank.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From j-marcus@pacbell.net@21:1/5 to All on Wed Feb 24 00:02:31 2021
    How about this?

    ?tacl macro
    #frame
    [#DEF fileCount TEXT |BODY| 0]
    [#DEF countRoutine ROUTINE
    |BODY|
    [#loop |WHILE| [#more]
    |DO| #set fileCount [#compute [fileCount] + [#argument FILENAME]]
    ]
    ]
    countRoutine [#filenames %*%]
    #output [fileCount] files counted
    #unframe


    Jon Marcus

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JShepherd@21:1/5 to All on Wed Feb 24 17:15:36 2021
    In article <7e36a4d7-9f05-4a39-a04b-44c485cb9e84n@googlegroups.com>, j- marcus@pacbell.net says...

    How about this?

    ?tacl macro
    #frame
    [#DEF fileCount TEXT |BODY| 0]
    [#DEF countRoutine ROUTINE
    |BODY|
    [#loop |WHILE| [#more]
    |DO| #set fileCount [#compute [fileCount] +
    [#argument F
    ILENAME]]
    ]
    ]
    countRoutine [#filenames %*%]
    #output [fileCount] files counted
    #unframe


    Jon Marcus


    #filenames *.*
    #filenames *.*
    ^
    *ERROR* Arithmetic overflow


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From j-marcus@pacbell.net@21:1/5 to All on Sat Feb 27 21:41:19 2021
    The TACL text buffer is 32,767 bytes. If #filenames expands to more than that, it will fail. Here is a version of the macro that limits #filenames to multiple smaller chunks. It should be more tolerant to a large number of file names:


    ?tacl macro
    #frame
    #push nextFile
    [#DEF fileCount TEXT |BODY| 0]
    [#DEF countRoutine ROUTINE
    |BODY|
    #result [#more]
    [#loop |WHILE| [#more]
    |DO| sink [#argument /TEXT nextFile/ WORD]
    #set fileCount [#compute [fileCount] + 1]
    ]
    ]

    [#loop |DO| |UNTIL|
    NOT [countRoutine [#filenames /MAXIMUM 800, PREVIOUS [nextFile]/ %*%]]]

    #output [fileCount] files counted
    #unframe


    Jon Marcus

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)