grep 사용법 – FIFA 월드컵 데이터로 실전 연습
unzip, wc -l, head 커맨드 사용정보 포함
grep 커맨드는 텍스트 파일에서 원하는 텍스트를 포함하는 줄을 찾는데 씁니다. 일정부분 sed 커맨드와 중복되는 부분이 있습니다. 그래도 텍스트 데이터를 다룰때 아주 유용하게 쓸 수 있는 커맨드입니다.
grep 커맨드를 사용법을 알아보기 전에 grep 커맨드를 적용할 텍스트 데이터를 내려받겠습니다. 웹브라우저를 열고, 아래 주소의 웹페이지로 갑니다.
www.kaggle.com
데이터 사이언스와 관련된 데이터와 코드를 찾아볼 수 있는 사이트입니다. 상금이 걸린 데이터 사이언스 시합도 종종 열립니다. 이곳에 회원가입을 한 후 로그인을 하던가 페이스북 아이디로 로그인을 합니다. 그런 다음 아래의 링크로 갑니다.
https://www.kaggle.com/abecklas/fifa-world-cup/
상단 오른쪽 부근에 Download (348KB) 라는 링크를 클릭합니다. 그러 fifa-world-cup.zip파일을 내려받을 수 있습니다. zip 파일안에 csv형식의 데이터 파일 세개가 압축해 들어가 있습니다. 다음 커맨드를 쓰면 csv파일들은 꺼낼 수 있습니다.
unzip fifa-world-cup.zip
세개의 csv파일중에 WorldCupMatches.csv에는 역대 피파 월드컵 경기 결과가 정리 되어 있습니다. 이중에서 한국과 관련된 데이터만 뽑아내려고 합니다. 이때 grep 커맨드를 사용할 수 있습니다.
한국은 영어로 Korea이므로 Korea라는 텍스트가 들어있는 줄을 grep 커맨드로 찾아 보겠습니다. 먼저 grep을 치고 그 다음에는 찾으려고 하는 텍스트인 Korea를 따옴표 안에 넣어 치고, 다음에는 어느 텍스트 파일에서 찾으려는 지를 알려주기위해 파일이름을 치면 됩니다.
grep "Korea" WorldCupMatches.csv
화면에 출력한 내용을 result.csv 파일에 저장해 보겠습니다. 커맨드 끝에 > result.csv 를 붙여 실행하면 됩니다.
grep "Korea" WorldCupMatches.csv > result.csv
result.csv 파일에 저장된 내용을 확인해 보겠습니다.
cat result.csv
자세히 보면 알겠지만 Korea가 하나만 있는 것이 아닙니다. 남한에 해당하는 Korea Repubic과 북한에 해당하는 Korea DPR이 있습니다. 그중에서 남한과 관련된 결과만 찾아보겠습니다. 그럴려면 “Korea” 대신 “Korea Republic”을 사용해 grep 커맨드를 실행해야 하겠습니다.
grep "Korea Republic" WorldCupMatches.csv > result.csv
다시 cat result.txt
로 확인해보면 Korea Republic에 대한 결과만 있음을 확인할 수 있습니다.
텍스트 파일이 총 몇개의 줄이 만들어졌는지를 확인해 보겠습니다. 그럴려면 wc 커맨드에 -l (알파벳 L의 소문자) 옵션을 쓰면 됩니다. WorldCupMatches.csv 와 result.csv 에 적용해 보겠습니다.
wc -l WorldCupMatches.csv wc -l result.csv
4500줄이 넘는 파일에서 31줄만 추려냈습니다.
이제 경기가 열린 연도와 상대국, 그리고 골 결과를 알아보겠습니다. 그럴려면 csv파일안에서 쉼표(,)로 구분된 각각의 값이나 텍스트가 무엇을 의미하는지 확인해봐야 하겠습니다. 이때 사용할 수 있는 커맨드는 head입니다. 아무 옵션 없이 head 커맨드를 파일이름과 함께 사용하면, 파일의 처음 다섯줄을 화면에 출력합니다.
head WorldCupMatches.csv
csv파일의 많은 경우는 첫째 줄에 어떤 데이터가 있는지에 대한 정보가 있습니다. WorldCupMatches.csv의 경우도 마찬가지 입니다. 첫째줄을 보면 어떤 데이터가 나열되어 있는지를 알 수 있습니다. head커맨드를 쓸때 -1 (숫자 1) 옵션을 쓰면 첫째줄만 화면에 출력합니다.
head -1 WorldCupMatches.csv
첫번째 데이터에 연도(year), …, 여섯번째 데이터에 홈팀 이름(Home Team Name), 일곱번째 데이터에 홈팀 골수(Home Team Goals), 여덟번째 데이터에 어웨이팀 골수(Away Team Goals), 아홉번째 데이터에 어웨이팀 이름(Away Team Name), …임을 알 수 있습니다.
따라서 우리는 첫번째 데이터(첫번째 쉼표전에 있는 데이터)와 여섯번째, 일곱번째, 여덟번째, 아홉번째 데이터를 뽑아내면 됩니다. 이건 이전에 배운 sed 커맨드를 써서 뽑아 보겠습니다.
일단 데이터와 쉼표를 하나로 묶어 정규표현(regular expression)으로 나타내보겠습니다. 쉼표가 나오기 전까지 쉼표가 아닌글자 [^,]를 모두 잡아내고 (아무 글자도 없는 것까지 포함) 쉼표를 잡아내려면 [^,]*, 를 쓰면 되겠습니다.
이 정규표현을 줄 맨처음을 나타내는 ^기호 다음에 9번을 반복해쓰면 아홉번째 데이터에 어웨이팀 이름(Away Team Name)까지 잡아낼 수 있습니다.
그런데 첫번째, 여섯번째, 일곱번째, 여덟번째, 아홉번째 데이터를 저자해야하므로 이에 해당하는 패턴은 소괄호로 묶어 ([^,]*), 로 잡아내면 되겠습니다.그 다음에는 나머지 모든 텍스트를 잡아내는 .*를 붙이면됩니다.
sed의 s/찾는패턴/바꿔쓸텍스트/ 를 이용해 ‘찾는패턴’에 ^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),([^,]*),([^,]*),([^,]*),.* 를 넣고, ‘바꿔쓸텍스트’에는 찾는 패턴에서 소괄호로 묶어 저장했던 5개의 값을 쉼표로 분리해 \1,\2,\3,\4,\5로 쓰면 되겠습니다.
cat result.csv | sed -r 's/^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),([^,]*),([^,]*),([^,]*),.*/\1,\2,\3,\4,\5/'
원하는 결과가 나왔습니다.
이제 지금까지 사용한 커맨드를 파이프(|)로 연결해, 한줄의 커맨드로 만들어 보겠습니다.
grep "Korea Republic" WorldCupMatches.csv | sed -r 's/^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),([^,]*),([^,]*),([^,]*),.*/\1,\2,\3,\4,\5/'
2006년 한국팀의 첫번째 경기였던 토고와의 경기는 결과를 정확하게 잡아내지 못했습니다. 그 이유는 데이터 중에 쉼표를 포함하는 데이터가 있기 때문입니다. 이런 경우는 “”로 묶어 나타내는데 이부분을 잡아내지 못해서 그렇습니다. 이 부분을 처리하는 방법은 나중에 한번 다뤄보겠습니다.
그 전에는 한줄정도는 수작업으로 데이터를 복사해서 붙이는 방법으로 처리하면 되겠습니다. 몇개 안되는 수작업만 남았을 경우에는 그부분은 그냥 수작업으로 하는 것이 모두를 자동화하는 코드를 만드는 것보다 더 빠를 수도 있습니다. 적절한 선택이 필요한 부분입니다.