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.