read: add -c flag to copy bytes instead of lines
parent
44f97f0cb1
commit
bdb228e14a
|
@ -12,7 +12,10 @@ cat, read \- catenate files
|
||||||
.B -m
|
.B -m
|
||||||
] [
|
] [
|
||||||
.B -n
|
.B -n
|
||||||
.I nline
|
.I nlines
|
||||||
|
] [
|
||||||
|
.B -c
|
||||||
|
.I nbytes
|
||||||
] [
|
] [
|
||||||
.I file ...
|
.I file ...
|
||||||
]
|
]
|
||||||
|
@ -54,9 +57,21 @@ The
|
||||||
flag causes it to continue reading and writing multiple lines until end of file;
|
flag causes it to continue reading and writing multiple lines until end of file;
|
||||||
.B -n
|
.B -n
|
||||||
causes it to read no more than
|
causes it to read no more than
|
||||||
.I nline
|
.I nlines
|
||||||
lines.
|
lines.
|
||||||
.PP
|
.PP
|
||||||
|
With the
|
||||||
|
.B -c
|
||||||
|
flag,
|
||||||
|
.I read
|
||||||
|
copies exactly
|
||||||
|
.I nbytes
|
||||||
|
of characters instead of lines. It is mutually exclusive with
|
||||||
|
.B -n
|
||||||
|
and
|
||||||
|
.B -m
|
||||||
|
flag.
|
||||||
|
.PP
|
||||||
.I Read
|
.I Read
|
||||||
always executes a single
|
always executes a single
|
||||||
.B write
|
.B write
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
int multi;
|
int multi;
|
||||||
int nlines;
|
int nlines;
|
||||||
|
vlong nchars;
|
||||||
char *status = nil;
|
char *status = nil;
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -52,30 +53,61 @@ lines(int fd, char *file)
|
||||||
}while(multi || --nlines>0);
|
}while(multi || --nlines>0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
chars(int fd, char *file)
|
||||||
|
{
|
||||||
|
char buf[8*1024];
|
||||||
|
vlong m;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for(m = 0; m < nchars; m += n){
|
||||||
|
n = sizeof(buf);
|
||||||
|
if(n > (nchars - m))
|
||||||
|
n = nchars - m;
|
||||||
|
if((n = read(fd, buf, n)) < 0){
|
||||||
|
fprint(2, "read: error reading %s: %r\n", file);
|
||||||
|
exits("read error");
|
||||||
|
}
|
||||||
|
if(n == 0){
|
||||||
|
if(m == 0)
|
||||||
|
status = "eof";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
write(1, buf, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
fprint(2, "usage: read [-m] [-n nlines] [-c nbytes] [files...]\n");
|
||||||
|
exits("usage");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
void (*proc)(int, char*);
|
||||||
int i, fd;
|
int i, fd;
|
||||||
char *s;
|
|
||||||
|
|
||||||
|
proc = lines;
|
||||||
ARGBEGIN{
|
ARGBEGIN{
|
||||||
|
case 'c':
|
||||||
|
nchars = atoll(EARGF(usage()));
|
||||||
|
proc = chars;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
nlines = atoi(EARGF(usage()));
|
||||||
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
multi = 1;
|
multi = 1;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
|
||||||
s = ARGF();
|
|
||||||
if(s){
|
|
||||||
nlines = atoi(s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* fall through */
|
|
||||||
default:
|
default:
|
||||||
fprint(2, "usage: read [-m] [-n nlines] [files...]\n");
|
usage();
|
||||||
exits("usage");
|
|
||||||
}ARGEND
|
}ARGEND
|
||||||
|
|
||||||
if(argc == 0)
|
if(argc == 0)
|
||||||
lines(0, "<stdin>");
|
(*proc)(0, "<stdin>");
|
||||||
else
|
else
|
||||||
for(i=0; i<argc; i++){
|
for(i=0; i<argc; i++){
|
||||||
fd = open(argv[i], OREAD);
|
fd = open(argv[i], OREAD);
|
||||||
|
@ -83,7 +115,7 @@ main(int argc, char *argv[])
|
||||||
fprint(2, "read: can't open %s: %r\n", argv[i]);
|
fprint(2, "read: can't open %s: %r\n", argv[i]);
|
||||||
exits("open");
|
exits("open");
|
||||||
}
|
}
|
||||||
lines(fd, argv[i]);
|
(*proc)(fd, argv[i]);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue