I am doing some geoip lookups using the geoiplookup command in Linux. This correctly returns the country codes for me but I need to break them down into continents instead of countries. I currently have a text file full of countries and am trying to determine the best way to convert these to continents using bash. I have a second text file called conversion and it looks like this:

United States:North America
Mexico:North America
Canada:North America
Argentina:South America
Bolivia:South America
Brazil:South America 
Chile:South America

I was thinking of doing some sort of loop for the name in the geo.txt file and grep the conversion.txt file and then print out anything after the :. I highly doubt that is the easiest/best way so just wanted to get a few opinions on it.

  • What is your desired output? – glenn jackman Jan 27 '14 at 21:26
  • Currently I have broken down into different files a username, and geo ip and I'm merging those into one file. So I basically want to match up the username to the continent instead of the username to the country. So a txt file or continent is fine as long as it's in the same order that the country one was since that maps to the username. – Eric Jan 27 '14 at 21:43

I would do the opposite of your proposition:

Loop on the coutry:continent (conversion.txt) file and use sed to make the change in a copy of geo.txt:




while read LINE; do
  COUNTRY="$(echo "${LINE}" | cut --delimiter=':' --fields=1)"
  CONTINENT="$(echo "${LINE}" | cut --delimiter=':' --fields=2)"

  command sed -i -e "s/${COUNTRY}/${CONTINENT}/g" "${TARGET_FILE}"

more "${TARGET_FILE}"

The geoiplookup command provides information in the form

GeoIP Country Edition: US, United States

So you can get the country information with

export IP=serverfault.com
country=$(geoiplookup "$IP" | awk 'BEGIN {FS=","} ; {print $2}' | sed 's/^ //')
echo $country
United States

You can then pass this to awk

awk -v search="$country" 'BEGIN {FS=":"} ; $0 ~ search {print $2}' conversion.txt
North America

I'll leave it as an exercise for you to put some error checking and other niceties into a script.

  • Hmmm.... I got your initial script working fine so I was going to try to put it in a for loop with multiple countries already in there and it fails. ---for i in cat /tmp/tmp.txt; do awk -v search="$i" 'BEGIN {FS=":"} ; $0 ~ search {print $2}' /tmp/conversion.txt; done--- It technically does the lookups but instead of outputting 7 continents to match the 7 countries, I get 23 continent outputs. I'll dig into it deeper. Thanks. – Eric Jan 27 '14 at 21:52

One thing you don't want to do is invoke sed/grep/awk for every iteration of a loop:

awk -F: 'NR==FNR {c[$1]=$2;next} {print c[$0]}' conversion.txt geo.txt > continents.txt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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