cat a.txt a b x c
cat b.txt d e a f
SOMEMAGICK *.txt a
Q: how can I show only the lines that are in all *.txt files?
And then to get the number of appearances stripped off, you could add ...
As per the comment by @Stephane the above won't work if a line appears multiple times within a single file. Here I sort and uniq each file first to avoid that:
Although now it's not a one-liner anymore. :)
When reading the first line of each file, increment
When reading each line, count the number of files in which that line has been seen (but you only need to bother doing this if the line has been seen in every previous file).
When there is no more input to read, print all lines that have been seen in all files.
Caution: As with several of the solutions posted here, this one also has a weakness. According to the question, if any of the input files is empty, there is supposed to be no output at all. However, since awk is a line-oriented tool, it ignores empty files. That is, the
With GNU awk, it's possible to fix this bug using the
Using GNU awk
You could do:
Which would be relatively efficient, but that's not easy to extend to an arbitrary number of files.
I like an easier solution using
This does work on your two input files, but may not behave as you expect on lines containing spaces, it will also output duplicate lines multiple times.
To remedy the second issue, just
The first is a bit more complicated, but I cheated a bit with the
For 2 files
This is no more complicated than making use of
NOTE: Depending on the data you may need to add a
For 3 or more
You can use the fact that if you compare any one file to the others that what ever is common across all of them as compared to this one file, then all files must share this common line. Again using
If we add some additional files into the mix:
Running our code produces this: