A very rough awk implementation:
BEGIN{
OLDFILENAME="";
}
FNR==1{
if (OLDFILENAME != "") {
printf("#### Processed (chars: %s - lines: %s)\n", FWC, FLC);
}
printf("#### Processing: %s\n", FILENAME);
OLDFILENAME=FILENAME;
FWC=0;
FLC=0;
}
{
printf("%04d - %s\n", FNR, $0);
FWC = FWC + length($0);
FLC = FLC + 1;
}
END{
if (OLDFILENAME != "") {
printf("#### Processed (chars: %s - lines: %s)\n", FWC, FLC);
}
}
Execute awk -f AWKFILE trapetz simpson
to get:
#### Processing: trapetz
0001 - x = 0:0.0001:7pi
0002 - plot(x, sin(x).*cos(x))
0003 - Area = trapz(x, sin(x).*cos(x))
#### Processed (chars: 70 - lines: 3)
#### Processing: simpson
0001 - f = inline(sin(x).*cos(x));
0002 - Area2 = quad(f, 0, 7pi, 1e-16)
#### Processed (chars: 57 - lines: 2)
The less than and symbol (<
) is opening the file up and attaching it to the standard input device handle of some application/program. But you haven't given the shell any application to attach the input to.
Example
These 2 examples do essentially the same thing but get their input in 2 slightly different manners.
opens file
$ cat blah.txt
hi
opens STDIN
$ cat < blah.txt
hi
Peeking behind the curtain
You can use strace
to see what's going on.
When we read from a file
open("blah.txt", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=3, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "hi\n", 65536) = 3
write(1, "hi\n", 3hi
) = 3
read(3, "", 65536) = 0
close(3) = 0
close(1) = 0
When we read from STDIN (identified as 0)
read(0, "hi\n", 65536) = 3
write(1, "hi\n", 3hi
) = 3
read(0, "", 65536) = 0
close(0) = 0
close(1) = 0
In the first example we can see that cat
opened the file and read from it, blah.txt
. In the second we can see that cat
reads the contents of the file blah.txt
via the STDIN file descriptor, identified as descriptor number 0.
read(0, "hi\n", 65536) = 3
Best Answer
locate pg_type.h
would find all the files withpg_type.h
in their path (so for instance if there was arpg_type.horn
directory, you'd end up displaying all the files in there).Without
-0
the output oflocate
can't be post-processed because the files are separated by newline characters while newline is a perfectly valid character in a file name.cat
without arguments writes to stdout what it reads from stdin, solocate | cat
would be the same aslocate
,cat
would just pass the output oflocate
along. What you need is to pass the list of files as arguments tocat
.That's what
xargs
is typically for: convert a stream of data into a list of arguments.-r
is to not callcat
if there's no input. Without-0
(which like-r
is not standard but found on many implementations, at least those where xargs is useful to anything),xargs
would just look for words in its input to convert into arguments, where words are blank separated and where backslash, single and double quotes can be used to escape those separators, so typically not the formatlocate
uses to display file names.That's why we use the
-0
option for bothlocate
andxargs
which uses the NUL character (which is the only character not allowed in a file path) to separate file names.Also note that
locate
is not a standard command and there exist a great number of different implementations with different versions thereof and different options and behaviours. The code above applies at least to relatively recent versions of the GNUlocate
andmlocate
implementations which are the most common on Linux based operating systems at least.