Discussion:
utility to count files matching a pattern
(too old to reply)
Henrik Paludan-Mørk
2021-02-22 15:03:59 UTC
Permalink
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
JShepherd
2021-02-22 15:48:00 UTC
Permalink
Post by Henrik Paludan-Mørk
I have need of a utility that will count files matching a disk file name
pattern
Post by Henrik Paludan-Mørk
.
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 */
Randall
2021-02-22 18:43:54 UTC
Permalink
Post by Henrik Paludan-Mørk
Post by Henrik Paludan-Mørk
I have need of a utility that will count files matching a disk file name
pattern
Post by Henrik Paludan-Mørk
.
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.
j-ma...@pacbell.net
2021-02-24 08:02:31 UTC
Permalink
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
JShepherd
2021-02-24 17:15:36 UTC
Permalink
Post by j-***@pacbell.net
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
Post by j-***@pacbell.net
ILENAME]]
]
]
countRoutine [#filenames %*%]
#output [fileCount] files counted
#unframe
Jon Marcus
1> #filenames *.*
#filenames *.*
^
*ERROR* Arithmetic overflow
2>
j-ma...@pacbell.net
2021-02-28 05:41:19 UTC
Permalink
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

Continue reading on narkive:
Loading...