mirror of git://git.suckless.org/sbase
xargs: add replace string flag (-I)
This commit is contained in:
parent
f14887c765
commit
8d97acc135
1
Makefile
1
Makefile
|
@ -78,6 +78,7 @@ LIBUTILSRC =\
|
||||||
libutil/strlcat.c\
|
libutil/strlcat.c\
|
||||||
libutil/strlcpy.c\
|
libutil/strlcpy.c\
|
||||||
libutil/strsep.c\
|
libutil/strsep.c\
|
||||||
|
libutil/strnsubst.c\
|
||||||
libutil/strtonum.c\
|
libutil/strtonum.c\
|
||||||
libutil/unescape.c\
|
libutil/unescape.c\
|
||||||
libutil/writeall.c
|
libutil/writeall.c
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2002 J. Mallett. All rights reserved.
|
||||||
|
* You may do whatever you want with this file as long as
|
||||||
|
* the above copyright and this notice remain intact, along
|
||||||
|
* with the following statement:
|
||||||
|
* For the man who taught me vi, and who got too old, too young.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Replaces str with a string consisting of str with match replaced with
|
||||||
|
* replstr as many times as can be done before the constructed string is
|
||||||
|
* maxsize bytes large. It does not free the string pointed to by str, it
|
||||||
|
* is up to the calling program to be sure that the original contents of
|
||||||
|
* str as well as the new contents are handled in an appropriate manner.
|
||||||
|
* If replstr is NULL, then that internally is changed to a nil-string, so
|
||||||
|
* that we can still pretend to do somewhat meaningful substitution.
|
||||||
|
* No value is returned.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
strnsubst(char **str, const char *match, const char *replstr, size_t maxsize)
|
||||||
|
{
|
||||||
|
char *s1, *s2, *this;
|
||||||
|
size_t matchlen, s2len;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if ((s1 = *str) == NULL)
|
||||||
|
return;
|
||||||
|
s2 = emalloc(maxsize);
|
||||||
|
|
||||||
|
if (replstr == NULL)
|
||||||
|
replstr = "";
|
||||||
|
|
||||||
|
if (match == NULL || *match == '\0' || strlen(s1) >= maxsize) {
|
||||||
|
strlcpy(s2, s1, maxsize);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
*s2 = '\0';
|
||||||
|
s2len = 0;
|
||||||
|
matchlen = strlen(match);
|
||||||
|
for (;;) {
|
||||||
|
if ((this = strstr(s1, match)) == NULL)
|
||||||
|
break;
|
||||||
|
n = snprintf(s2 + s2len, maxsize - s2len, "%.*s%s",
|
||||||
|
(int)(this - s1), s1, replstr);
|
||||||
|
if (n == -1 || n + s2len + strlen(this + matchlen) >= maxsize)
|
||||||
|
break; /* out of room */
|
||||||
|
s2len += n;
|
||||||
|
s1 = this + matchlen;
|
||||||
|
}
|
||||||
|
strlcpy(s2 + s2len, s1, maxsize - s2len);
|
||||||
|
done:
|
||||||
|
free(*str);
|
||||||
|
*str = s2;
|
||||||
|
return;
|
||||||
|
}
|
2
util.h
2
util.h
|
@ -63,6 +63,8 @@ size_t estrlcpy(char *, const char *, size_t);
|
||||||
#define strsep xstrsep
|
#define strsep xstrsep
|
||||||
char *strsep(char **, const char *);
|
char *strsep(char **, const char *);
|
||||||
|
|
||||||
|
void strnsubst(char **, const char *, const char *, size_t);
|
||||||
|
|
||||||
/* regex */
|
/* regex */
|
||||||
int enregcomp(int, regex_t *, const char *, int);
|
int enregcomp(int, regex_t *, const char *, int);
|
||||||
int eregcomp(regex_t *, const char *, int);
|
int eregcomp(regex_t *, const char *, int);
|
||||||
|
|
8
xargs.1
8
xargs.1
|
@ -1,4 +1,4 @@
|
||||||
.Dd 2015-10-08
|
.Dd 2023-07-30
|
||||||
.Dt XARGS 1
|
.Dt XARGS 1
|
||||||
.Os sbase
|
.Os sbase
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -8,6 +8,7 @@
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl rtx
|
.Op Fl rtx
|
||||||
.Op Fl E Ar eofstr
|
.Op Fl E Ar eofstr
|
||||||
|
.Op Fl I Ar replstr
|
||||||
.Op Fl n Ar num
|
.Op Fl n Ar num
|
||||||
.Op Fl s Ar num
|
.Op Fl s Ar num
|
||||||
.Op Ar cmd Op Ar arg ...
|
.Op Ar cmd Op Ar arg ...
|
||||||
|
@ -44,6 +45,11 @@ Normally the command is executed at least once even if there are no arguments.
|
||||||
Use
|
Use
|
||||||
.Ar eofstr
|
.Ar eofstr
|
||||||
as a logical EOF marker.
|
as a logical EOF marker.
|
||||||
|
.It Fl I Ar replstr
|
||||||
|
Use
|
||||||
|
.Ar replstr
|
||||||
|
as the placeholder for the argument.
|
||||||
|
Sets the arguments count to 1 per command line.
|
||||||
.It Fl s Ar num
|
.It Fl s Ar num
|
||||||
Use at most
|
Use at most
|
||||||
.Ar num
|
.Ar num
|
||||||
|
|
16
xargs.c
16
xargs.c
|
@ -195,10 +195,11 @@ usage(void)
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int ret = 0, leftover = 0, i;
|
int ret = 0, leftover = 0, ri = 0, i;
|
||||||
size_t argsz, argmaxsz;
|
size_t argsz, argmaxsz;
|
||||||
size_t arglen, a;
|
size_t arglen, a;
|
||||||
char *arg = "";
|
char *arg = "";
|
||||||
|
char *replstr;
|
||||||
|
|
||||||
if ((argmaxsz = sysconf(_SC_ARG_MAX)) == (size_t)-1)
|
if ((argmaxsz = sysconf(_SC_ARG_MAX)) == (size_t)-1)
|
||||||
argmaxsz = _POSIX_ARG_MAX;
|
argmaxsz = _POSIX_ARG_MAX;
|
||||||
|
@ -225,6 +226,11 @@ main(int argc, char *argv[])
|
||||||
case 'E':
|
case 'E':
|
||||||
eofstr = EARGF(usage());
|
eofstr = EARGF(usage());
|
||||||
break;
|
break;
|
||||||
|
case 'I':
|
||||||
|
nflag = 1;
|
||||||
|
maxargs = 1;
|
||||||
|
replstr = EARGF(usage());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
} ARGEND
|
} ARGEND
|
||||||
|
@ -235,6 +241,8 @@ main(int argc, char *argv[])
|
||||||
for (; i < argc; i++) {
|
for (; i < argc; i++) {
|
||||||
cmd[i] = estrdup(argv[i]);
|
cmd[i] = estrdup(argv[i]);
|
||||||
argsz += strlen(cmd[i]) + 1;
|
argsz += strlen(cmd[i]) + 1;
|
||||||
|
if (!strcmp(cmd[i], replstr))
|
||||||
|
ri = i;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cmd[i] = estrdup("/bin/echo");
|
cmd[i] = estrdup("/bin/echo");
|
||||||
|
@ -252,7 +260,11 @@ main(int argc, char *argv[])
|
||||||
leftover = 1;
|
leftover = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cmd[i] = estrdup(arg);
|
if (ri > 0)
|
||||||
|
strnsubst(&cmd[ri], replstr, arg, 255);
|
||||||
|
else
|
||||||
|
cmd[i] = estrdup(arg);
|
||||||
|
|
||||||
argsz += arglen + 1;
|
argsz += arglen + 1;
|
||||||
i++;
|
i++;
|
||||||
a++;
|
a++;
|
||||||
|
|
Loading…
Reference in New Issue