I have a problem with the output produced by the masscan utility with the -oL options ("grep-able" output); for instance, it outputs this:
Host: 143.137.155.7 () Ports: 80/open/tcp////
Host: 177.105.21.41 () Ports: 8080/open/tcp////
Host: 187.78.236.98 () Ports: 80/open/tcp////
Host: 177.137.76.220 () Ports: 8080/open/tcp////
Host: 177.105.10.112 () Ports: 9000/open/tcp////
Host: 191.232.34.9 () Ports: 80/open/tcp////
Host: 179.55.65.144 () Ports: 80/open/tcp////
Host: 177.83.203.147 () Ports: 8080/open/tcp////
Host: 177.182.50.124 () Ports: 8000/open/tcp////
The above is neither very readable nor easy to understand.
How can I use Linux command-line utilities, e.g. sed, awk, or grep, to output something as follows, using the file above?
143.137.155.7:80
177.105.21.41:8080
187.78.236.98:80
177.137.76.220:8080
177.105.10.112:9000
While Tom's answer is probably the best one for the job, it never hurts to have other options.
Using
awk
andcut
:There is almost certainly a more efficient way to do this entirely in
awk
but I am not sure how exactly.How about
Explanation:
s/regex/replacement/
substitutesregex
withreplacement
^
matches the start of the stringHost:
matches itself[0-9.]
is a character range that matches the digits 0 to 9 and.
[0-9.]*
matches zero or more digits/dots\([0-9.]*\)
makes the matched IP address available in the replacement as\1
.
matches any single character.*
matches zero or more single characters (i.e. any string)Ports:
matches itself\([0-9]*\)
matches a string of digits and makes it available as\2
.*$
matches the rest of the stringThe flag
g
at the end applies the replacement to all matches rather than the first match on each line. In this case, there can only be one match (the entire line), so the flag doesn't do anything. I type it out of habit.awk can take regex as a delimiter. Split on either / or 1+ spaces and then print the columns.