두 개의 텍스트 파일 합치는 방법 (join)
글쓴이: maniac / 작성시간: 화, 2006/08/22 - 7:11오후
[root@xmen shell]# cat foo1.txt foo_1 foo_2 foo_3 foo_4 [root@xmen shell]# cat foo2.txt foo_a,foo_b,foo_c foo_x,foo_y,foo_z foo_m,foo_n,foo_o
라는 두 개의 텍스트 파일을
[root@xmen shell]# cat foo3.txt foo_1,foo_a,foo_b,foo_c foo_2,foo_x,foo_y,foo_z foo_3,foo_m,foo_n,foo_o
형식과 같이 만들려고 할때..
가장 효율적인 방식은 무엇인가요?
(단, 두 파일모두 라인 수는 같음.)
제가 작업하려는 파일이 꽤 커서,
for join_item in `awk '{print $1}' foo1.txt` do awk 'BEGIN{FS=","; OFS=";"} {print "'$join_item'",$1,$2,$3}' foo2.txt > foo3.txt done
형식으로 작업하니, 파일 i/o가 너무 많이 일어나서
시간이 너무 오래 걸리는군요..
라인넘버도 없어서 join 시키기도 안될것 같고...;;
뭐, 좋은 방법이 없을까요..;;
머리가 나빠 하루종일 고민하네요... -_-;;;
도움 부탁드립니다.
Forums:
paste(1)
paste -d, foo_1.txt foo_2.txt > foo_3.txt
역으로 cut(1)도 있습니다.
man paste
man cut
http://kldp.org/node/45122
http://kldp.org/node/45122
http://blacksun.ivyro.net/rgb.htm
이 문서, rgb.txt를 기반으로 paste와 vim으로 만들었어요.
감사합니다~!!
paste가 있는줄 몰랐습니다. (겨우 셸 프로그래밍한지 한달밖에 안되서..-_-;;)
join에서 맘대로 안되길래 좌절중이었거든요.. ^^
좋은답변 감사드립니다~!
좋은 하루 되세요~!!
paste 상당히
paste 상당히 멋지네요..
참고로 펄로도 할수 있습니다.
메모리리에 다 로드해도 된다면.. 더 멋지고 빠르게도 할 수 있죠.
아, 그렇군요..!
제가 아직 awk랑 sed 쓸 줄 아는 수준 밖에 안되는 지라.. ^^;;;
또 로그 파일이라 메모리에 다 올라간다고 함부로 단정 지을 수도 없구요...
참고했다가 나중에 응용 해 보도록 하겠습니다~!
좋은 하루 되시구요~~!!!
답변 감사드립니다~!!
오우 PERL로 제가
오우 PERL로 제가 달아드릴려했는데
pung96님이 먼저 다셨네요.
PERL의 정규표현식만 약간 익혀도 쓸데가 제법 많습니다.
maniac님 조금만 배워도 쓸모있습니다^^
#!/usr/bin/perl
##########################################################
for ($i=0;$i<1;$i++,$i--) {
select(undef,undef,undef, 0.5000),print "사랑합니다.\n" if((!$You_Love_Me)&&($Dead_of_My_Heart));
}
#!/usr/bin/perl
##########################################################
for ($i=0;$i<1;$i++,$i--) {
select(undef,undef,undef, 0.5000),print "사랑합니다.\n" if((!$You_Love_Me)&&($Dead_of_My_Heart));
}
그런데 paste가 훨씬
그런데 paste가 훨씬 빠르네요 paste로 1M 라인 2Mbyte정도 되는 파일을 합쳐봤는데 평균시간 0.2초.
위의 제 펄코드로 합쳤을때 1.7초.
문제는 파일하나를 읽어들이는데만 0.5초가량이 걸리네요.
전에 2기가바이트 파일 읽을때 메가당 그렇게 오래 안걸렸던것 같거든요.
뭐가 문젤까요.
펄은 속도보단 실용성을 위주로 만들어서 그런게아닌가 합니다.
해보진 않았지만
파일의 용량이 클때는 배열변수에 바로 적용하기 보다는
open (HANDLE,"./route");
while(){
$FILE .= $_;
}
print $FILE;
처럼 하나씩 읽어내는게 더 낫다고들 합니다.
물론 2기가나되는 파일을 읽어보진 않았습니다 ^^;(2기가정도의 파일이 없어서...)
컴파일후 실행하는 것도 빠르게 돌리는 방법중 하나겠죠.
#!/usr/bin/perl
##########################################################
for ($i=0;$i<1;$i++,$i--) {
select(undef,undef,undef, 0.5000),print "사랑합니다.\n" if((!$You_Love_Me)&&($Dead_of_My_Heart));
}
#!/usr/bin/perl
##########################################################
for ($i=0;$i<1;$i++,$i--) {
select(undef,undef,undef, 0.5000),print "사랑합니다.\n" if((!$You_Love_Me)&&($Dead_of_My_Heart));
}
실제로 돌려보면
실제로 돌려보면 속도는 배열에 넣거나 foreach를 사용하는것이 while보다는 확실히 빠릅니다.
파일이 클수록 더그렇구요(IO가 차지하는 비중이 커지니까요).
아무래도 한번에 읽는것이 버퍼나 디스크 seek Time에 유리할 겁니다.
다만 파일이 너무 크면 그걸 다 메모리에 로드하기 어려워지겠지요.
지금 재미있는 결과를 만들었습니다.
1. 1M라인, 2Mbyte 파일 2개 합치기
perl : 2.27초
paste : 0.3x초
2. 1M 라인 66Mbyte 파일 2개 합치기
perl 스크립트 : 3.8초
paste : 3.5초
3. 1M 라인 329Mbyte 파일 2개 합치기
perl : 13초
paste : 25초
아무래도 paste는 용량에 perl은 라인수에 더 영향을 받는가봅니다.
오우 펄은 한 라인씩
오우
펄은 한 라인씩 읽어들여서 그런지도 모르겠네요.
그리고 배열에 담는 것이 더욱 빠르다니 다음부턴 그렇게 적용하는 것이 더욱 좋을듯 하군요.
하지만 말씀하신대로 메모리를 초과한다면 달라지겠지만요
#!/usr/bin/perl
##########################################################
for ($i=0;$i<1;$i++,$i--) {
select(undef,undef,undef, 0.5000),print "사랑합니다.\n" if((!$You_Love_Me)&&($Dead_of_My_Heart));
}
#!/usr/bin/perl
##########################################################
for ($i=0;$i<1;$i++,$i--) {
select(undef,undef,undef, 0.5000),print "사랑합니다.\n" if((!$You_Love_Me)&&($Dead_of_My_Heart));
}
댓글 달기