Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Trying to cram all of the following into the title was hard, so this is what I really mean:

I am doing a tail -F access.log to watch an Apache2 log in realtime. The first thing on each line is an IP address followed by a space. I also have an unchanging CSV file where each row is an IP address, comma, name. For example:,John Smith,Jane Doe

Deliverable: I want to follow my access log as before, but if the CSV happens to contain a row with the same IP address that the current logfile line starts with, then insert the person's name at the start of the line.

For example, a line like this: - - [22/Aug/2013:13:41:24 +0000] "GET /index.php ...

Should instead render as:

John Smith - - [22/Aug/2013:13:41:24 +0000] "GET /index.php ...

Ideally, I would like to do this entirely by piping some regex commands together. So far, my biggest issue is that grep doesn't accept a pattern on stdin, it expects the subject on stdin (unless I'm missing something). Also, I have no problem transforming the CSV into some better format if required. Thanks.

share|improve this question
up vote 1 down vote accepted

Here's a POSIX shell solution

tail -f access.log | while read -r line;do
    ip=${line%% *}
    name=$(grep -F "$ip" your_csv_file|cut -d, -f2)
    if [ -z "$name" ];then
        printf "%s\n" "$line"
        printf "%s\n" "$name $line"


Two improvements made to the solution:

  • -r switch added to read so that it doesn't evaluate escape sequences in the lines it reads
  • -F switch added to grep so that it treats the IP as a fixed string rather than a regular expression.
share|improve this answer

I would do this with a little Perl script:

#!/usr/bin/env perl

## Open the first argument, the .csv file
## Collect the list of ips and names in the %ips hash
## Now open the second argument, the log file to be watched. The
## trick here is to open by piping through tail -F
 open($f,"-|", "tail -F $ARGV[1]");
 ## Get the ip
 ## Prepend the associated name from the .csv file if one is defined
  s/$ip/$ips{$ip} $ip/ if defined($ips{$ip});
 ## Print the line

Save that in your $PATH as, make it executable (chmod +x and then run it like this: /home/foo/ips.csv /var/log/apache2/access.log
share|improve this answer

grep can get the patterns from stdin, but it cannot get the text from stdin at the same time. See the -f option. If your shell supports process substitution, you can simulate it with

produce_patterns | grep -f- <( produce_input )

For example:

( echo b; echo y ) | grep -f- <( for i in {a..z} ; do echo $i ; done )


share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.