Reputation: 169
i have two files:
File_1.txt
PROCESS1 1234
PROCESS2 1235
PROCESS3 1236
PROCESS4 1237
File_2.txt
1.2.3.4 1234
1.2.3.5 1235
1.2.3.6 1236
1.2.3.7 1234
1.2.3.8 1234
1.2.3.9 1235
1.2.3.8 1234
1.2.3.8 1234
The first file, has a process name and it's pid, and the second file, has an IP and a PID too.. what i need is to find the matching PID from the first file in the second file, and output somenthing like this
Desired_output.txt
PROCESS1 1234 1.2.3.4 1
PROCESS1 1234 1.2.3.8 3
PROCESS2 1235 1.2.3.5 1
PROCESS2 1235 1.2.3.9 1
PROCESS3 1236 1.2.3.6 1
PROCESS4 1237 - 0
Where, the first column is the process name, the second column is the PID , the third column are the ips in the file and the fourth column is the times that the ip is listed in the file_2.txt
Thanks in advance
Upvotes: 1
Views: 166
Reputation: 3838
Using join
(who is probably the best solution) :
$ join -j2 <(sort -k2 test1.txt) <(sort -k2 test2.txt)
1234 PROCESS1 1.2.3.4
1234 PROCESS1 1.2.3.7
1234 PROCESS1 1.2.3.8
1234 PROCESS1 1.2.3.8
1234 PROCESS1 1.2.3.8
1235 PROCESS2 1.2.3.5
1235 PROCESS2 1.2.3.9
1236 PROCESS3 1.2.3.6
Then you could try something like :
$ cat test.sh
#!/bin/bash
file1=test1.txt
file2=test2.txt
joinOutput=$(join -j2 <(sort -k2 "$file1") <(sort -k2 "$file2"))
countOutput=$(echo "$joinOutput"|awk '{key=$2" "$1" "$3; if(key in t){t[key]=t[key]+1} else {t[key]=1}} END {for (l in t){print l" "t[l]}}'|sort)
echo "$countOutput"
cat "$file1" <(echo "$countOutput")|cut -d " " -f2|sort|uniq -u|while read; do
echo "$REPLY - 0"
done
$ ./test.sh
PROCESS1 1234 1.2.3.4 1
PROCESS1 1234 1.2.3.7 1
PROCESS1 1234 1.2.3.8 3
PROCESS2 1235 1.2.3.5 1
PROCESS2 1235 1.2.3.9 1
PROCESS3 1236 1.2.3.6 1
1237 - 0
Otherwise, you could try something like :
$ cat test.sh
#!/bin/bash
file1=test1.txt
file2=test2.txt
joinOutput=$(
while read c11 c12; do
while read c21 c22; do
[[ $c22 = $c12 ]] && echo "$c11 $c12 $c21"
done < "$file2"
done < "$file1"
)
countOutput=$(echo "$joinOutput"|awk '{if($0 in t){t[$0]=t[$0]+1} else {t[$0]=1}} END {for (l in t){print l" "t[l]}}'|sort)
echo "$countOutput"
cat "$file1" <(echo "$countOutput")|cut -d " " -f2|sort|uniq -u|while read; do
echo "$REPLY - 0"
done
$ ./test.sh
PROCESS1 1234 1.2.3.4 1
PROCESS1 1234 1.2.3.7 1
PROCESS1 1234 1.2.3.8 3
PROCESS2 1235 1.2.3.5 1
PROCESS2 1235 1.2.3.9 1
PROCESS3 1236 1.2.3.6 1
1237 - 0
Upvotes: 2
Reputation: 23015
Try the join
command, it let's you do exactly that.
Only restriction I can think of, is that the files must be sorted. So if you don't care about preserving the order of the output lines you can use join
.
Manual page: http://linux.die.net/man/1/join
Upvotes: 2