퍼펙트 센스

13035539_perfect_sense_poster

이 영화를 제대로 표현할 수 있는 한 문장은 바로 이것이다.
“잃을 수록 완벽해진다.”

영화에서 인류는 조금씩 본인들의 감각을 잃어간다.
흔히 오감이라 말하는 감각 중 미각, 후각, 청각, 시각을 순서대로 잃어간다.

인류는 각각의 감각을 잃기 전 무언가 광기에 휩싸인 듯 특정한 행동을 보인다. 잃어가는 감각과 관련된 행동들인데 영화를 보면 너무나도 섬뜩하게 표현된다.
감각을 잃어가는 인류는 저마다 자신들의 현실을 받아들이고 또 그렇게 적응해나간다. 간신히 새로운 삶에 적응할 즈음에 또 다른 감각의 상실이 찾아온다. 상실 이전의 광기는 상실에 간신히 적응하려 했던 인류의 마지막 몸부림을 처참히 부숴버린다. 스스로 생각해낸, 자신들의 새로운 삶의 방식을 상실 이전의 광기가 모두 원위치 시킨다.

상실되는 감각을 살펴보면 뒤로 갈수록 점점 더 삶에 직접적인 영향을 끼치는 것들이다. 사실 오감 상실의 단계까지는 가지 않는 감각이 있는데 바로 ‘촉각’이다. 사람들은 마지막으로 시각을 잃고 나머지 하나 남은 ‘촉각’이 ‘완벽한 감각'(퍼펙트 센스)이라는 것을 깨닫는다. 남주와 여주는 헤어짐 끝에 간신히 만나고 서로를 인식하자마자 시각을 잃고는 ‘촉각’으로 대화하며 영화는 끝이 난다.

현대 사회에서 촉각은 인간의 오감 중 가장 덜 퍼펙트 하다고 여겨지는 감각이 아닐까 한다. 사실 촉각은 통증과 압력을 느끼는 중요한 역할을 하기 때문에 어찌 보면 가장 중요하다고 할 수 있는데, 영화에서 말하는 퍼펙트 센스로서의 촉각은 ‘다른 사람과의 교감’이 아닐까 한다. 자신과 타인의 의사소통에 있어 나머지 네 개의 감각도 물론 중요하지만 가장 중요한 것은 바로 ‘촉각’이라고…

1) 리눅스 명령어 awk, 원하는 항목만 추출하여 더하기

리눅스 명령어 중 awk를 사용하여 여러 줄의 문자열 중 각 라인에서 원하는 부분만 추출하여 더하는 간단한 스크립트를 작성한다.
예를 들어 다음과 같은 문자열 파일이 있을 때(각 항목은 버티컬 바(‘|’)로 구분되어 있다, 파일 이름은 ‘sales.txt’)
apple|1|3000
banana|2|2400
grape|4|3500

첫 번째 항목은 품목명을 나타내고 두 번째 항목은 판매 개수, 세 번째 품목은 판매 단가를 나타낸다.
여기서 총 판매액을 구하고 싶을 때, 각 라인의 판매 개수 * 판매 단가를 모두 더하면 되는데 이를 awk 라는 명령어를 사용하면 편하게 구현할 수 있다.

먼저 세 가지 항목 중 첫 번째는 제외하고 나머지 두 번째와 세 번째 항목을 추출해야 한다.

awk '{ \
      split($0, split_line, "|");  \
      print split_line[2];  \
      print spilt_line[3]; \
}' sales.txt

awk 명령어를 사용하는 방법은 크게 두 가지가 있는데 첫 번째는 위와 같이 awk 명령어 기술 후 awk 문을 바로 이어서 붙이는 것이고
다른 하나는 awk문을 파일에 저장한 후 ‘awk -f awk파일명’ 과 같은 방식으로 사용하는 것이다.
awk문이 길어질 경우 명령행에 적는 것이 복잡해지기 때문에 awk문 파일로 관리하는 것이 더 합리적이다.

이제 위 코드 설명에 들어가자면,
awk문은 ‘{ }’ 사이에 기술한다. 위 코드에서는 2~4번째 줄이 awk문이 되는 것이다.
2: split 함수를 사용한다. awk는 다양한 내장함수를 사용할 수 있는데, 구분자를 기준으로 문자열을 자르고 싶을 때 사용하는 함수가 바로 split이다.
split 함수의 첫 번째 인자는 자르고자 하는 대상 문자열이며, 위 코드에서는 ‘$0’이다. awk에서 $0은 라인 전체를 의미한다.
split 함수의 두 번째 인자는 대상 문자열을 자르고 난 후 저장할 배열 변수이다. 위 코드에서는 split_line이라는 변수에 저장시킨다.
세 번째 인자는 구분자를 지정한다. sales.txt 파일에서 각 라인의 구분자는 버티컬 바(‘|’)이기 때문에 구분자를 “|”으로 지정해준다.

3: 구분자로 잘라진 문자열들이 저장된 배열 변수 split_line의 두 번째 인덱스를 출력한다.
다른 프로그래밍 언어의 배열과 달리 첫 번째 인덱스가 1부터 시작하기 때문에 split_line 변수에는 1:apple, 2:1, 3:3000 과 같은 식으로 저장된다.
두 번째 인덱스를 출력했기 때문에 sales.txt 파일의 각 라인의 두 번째 항목인 판매 개수가 출력된다.

4: 세 번째 인덱스를 출력한다.
세 번째 인덱스는 sales.txt 파일의 각 라인의 세 번째 항목인 판매 단가가 출력된다.

우리는 판매 개수와 판매 단가를 곱한 후 모두 더한 값을 구하는 것이 최종 목표이기 때문에 위 코드로는 구할 수 없다.
위 코드를 고쳐서 판매 개수와 판매 금액을 곱한 후 출력해보자

awk '{ \
      split($0, split_line, "|");  \
      line_sum = split_line[2] * spilt_line[3];  \
      print line_sum; \
}' sales.txt

2: 판매 개수(split_line[2])와 판매 금액(split_line[3])을 곱한 후 line_sum 변수에 저장한다.
3: line_sum 변수를 출력한다.

위 코드를 실행시키면 다음과 같은 출력값을 확인할 수 있다.

3000
4800
14000

이제 세 개의 값을 더한 최종 판매 금액만 구하면 된다.

awk 'BEGIN{ \
    total_sum=0; \
}{ \
    split($0, split_line, "|");  \
    total_sum += split_line[2] * split_line[3]; \
}END{ \
    print total_sum; \
}' sales.txt

BEGIN과 END라는 키워드가 눈에 띌 것이다. awk문 내부는 해당 파일의 각 라인을 읽으면서 수행된다. sales.txt는 총 라인수가 3이기 때문에 awk ‘{}’ 내부는 세 번 실행되는 것이다. 그런데 이번 예제와 같이 각 라인에 영향을 받지 않고 파일 전체에서 관리하고 싶은 코드가 있을 경우에는 BEGIN과 END를 사용한다. 키워드의 의미 그대로 파일을 처음 읽어들일 때 BEGIN{ } 내부가 실행되고 파일을 전부 읽어들인 후 END{ } 내부가 실행된다.
2: BEGIN 내부에 total_sum 이라는 변수를 선언하며 0을 대입하고 있다.
5: 2번째 줄에서 선언한 total_sum 변수에 판매 개수 * 판매 단가 값을 누적 합산해주고 있다. ( += )
7: 마지막으로 프로그램 종료 전, total_sum을 출력한다.

위 코드를 실행하면 다음과 같은 출력값을 확인할 수 있다.

21800

따라서 총 판매 금액은 21,800이 되는 것이다.
동일한 기능을 수행하는 프로그램을 파이썬이나 자바로도 충분히 작성할 수 있지만, 이런 간단한 스크립트 연산만으로도 원하는 값을 구할 수 있다면 굳이 파이썬, 자바 코드까지 사용할 필요는 없다는 게 내 생각이다.

awk는 사용자의 능력에 따라서 무궁무진하게 이용될 수 있는 명령어이다. 위에서 소개된 것들은 awk의 전체 기능 중에서도 가장 간단한 것들만 사용한 것으로
나머지 awk 기능을 자유자재로 사용할 수 있다면 그것만으로도 awk라는 또다른 강력한 언어 스킬을 보유하게 되는 것이다.

오만과 편견

영화 제목만 들었을때는 무거운 주제의 영화가 아닌가 싶었고
영화를 보는 내내 도대체 영화와 제목이 무슨 상관인가 생각했으며
영화가 끝나고 나서야 영화 제목을 잘 지었다고 감탄하게 된다.

실제로 영화 대사 도중 ‘오만’과 ‘편견’이라는 단어가 자주 등장하여 남주인공의 성격을 묘사한다. 묘사의 주체는 주로 여주인공이다.

영화의 배경은 17~18세기 영국으로 당시의 생활풍습이 잘 나타나있다.
여주인공 역할을 맡은 배우 키이라 나이틀리는 영화 특유의 색감과 더불어 매력적으로 출연하는데 이또한 영화의 볼거리 중 하나이다.

쉘 스크립트에서 sqlite3 작업하기

보통 파이썬 환경에서 sqlite3를 작업하게 되는 경우가 많은데 이는 sqlite3 모듈이 굉장히 잘 되어있기 때문이다.
하지만 파이썬까지 가지 않고 쉘에서 db 작업을 하고 싶을 때가 있는데 이는 다음과 같이 하면 된다.

#insert
sqlite3 dbname.db "insert into tablename (date, col1, col2) \
                   values ('2013-11-11', 'data1', 'data2');"

#select
echo "select * from tablename;" | sqlite3 dbname.db > target.txt

insert 작업을 할 때는 sqlite3 뒤에 데이터베이스 이름을 써주고 그 뒤에 sql문을 적어주면 된다.
select 작업에서는 echo 명령어 뒤에 sql문을 적은 뒤 파이프 라인 후 sqlite3 데이터베이스이름, 그리고 select 결과물을 저장할 파일 이름을 기술하면 된다.

하둡 스트리밍 시 대용량 파일을 -file 파라미터로 사용할 경우

하둡 스트리밍 시 대용량 파일을 -file 파라미터로 사용할 경우에 “No space left on device” 에러가 날 수 있다.
문자 그대로 사용 가능한 용량이 부족하여 발생하는 에러인데 이럴 때는 하둡 스트리밍 파라미터로 해결이 가능하다.

 -D stream.tmpdir=(로컬 temp 디렉토리 경로)

로컬 temp 디렉토리 경로는 로컬 내부에 존재해야 하며 -file 파라미터로 주는 대용량 파일이 .jar 형태로 저장된다.

django Built-in template tags and filters 소개

django의 template 기능을 쓰면서 정리함.

  1. 반복문
    template에서도 반복문을 사용할 수 있다. 기본적인 프로그래밍 언어와 마찬가지로 while문과 for문을 지원한다.
#소스코드 1
<ul>
{% for name in name_list %}
    <li>{{ name }}</li>
{% endfor %}
</ul>

django의 for문과 형태가 유사하다. 다만 django의 template에서는 {% %}블럭으로 감싸주어야 한다. jsp와 상당히 유사함.
name_list는 django의 자료형인 list나 dict, tuple등이 올 수 있다.
예를 들어,

#소스코드 2
name_list = ['jane', 'michael', 'justine']

name_list 변수에 위와 같은 리스트 자료형이 담긴 후 template에 넘겨줬을 때, 소스코드 1의 실행 결과는 다음과 같다.

<ul>
  <li>jane</li>
  <li>michael</li>
  <li>justine</li>
</ul>

template로 넘겨주는 변수(위에서는 name_list)에 list가 아닌 dict 자료형을 대입했을 때의 상황을 살펴보자.

#소스코드 3
person_dic = {"name":"jane", "addr":"earth", "gender":"female"}

#위 변수를 template에 넘겨줬을 때 person_dic을 iteration하는 경우
<ul>
{% for key, value in person_dic.items %}
 <li>{{ key }} : {{ value }}</li>
{% endfor %}
</ul>

소스코드 3의 for문 부분에서 for와 in 사이에 key, value가 설정된 것을 알 수 있다. dict는 key와 value로 이루어져있기 때문에 for문에서도 각각 쌍으로 나눠서 반복문에 설정된다.
위 코드의 실행결과는 다음과 같다.

<ul>
   <li>name : jane</li>
   <li>addr : earth</li>
   <li>gender : female</li>
</ul>