Mass Lowercasing of File Names

· klm's blog


Original post is here: eklausmeier.goip.de

Task at hand: lowercase ca. half a million file names. The obvious solution would be to use the mv command together with tr to accomplish the job:

1for i in A B C ...; do mv $i `echo $i | tr '[A-Z]' '[a-z]'`; done

Each file would spawn two processes: one for the tr and one for the mv itself. The echo command is a shell built-in. tr is not part of BusyBox, so BusyBox cannot be used to get rid of the process flood.

To avoid the masses of process creations, I created below simple C program instead:

 1/* Lower case multiple files, so we avoid unnecessary sub-processes
 2   Elmar Klausmeier, 31-Jan-2022
 3*/
 4#include <stdio.h>
 5#include <ctype.h>
 6#include <string.h>
 7
 8int main(int argc, char *argv[]) {
 9	int i, st=0;
10	char *fn, fnLower[256], *p, *q;
11
12	for (i=1; i<argc; ++i) {
13		fn=p=argv[i], q=fnLower;
14		while ((*q++ = tolower(*p++)) != '\0')
15			;
16		if (strcmp(fn,fnLower) == 0) continue;
17		if ((st = rename(fn,fnLower)) != 0) {
18			printf("Cannot lowercase %s, code=%d, error %s\n",
19				fn,st,strerror(st));
20			break;
21		}
22	}
23
24	return st;
25}

Calling is thus:

1multilc A B C ...

The limit of this is just the maximal number of bytes on the command line. This can be queried:

1$ getconf ARG_MAX
22097152

The result is in bytes.

Also see Parallel Mass-File Processing.

#C