隨筆-314  評論-209  文章-0  trackbacks-0

          一個大型文件(總之不小),要求刪除該文件的最后一行,求一種效率比較高的解決方法。

          測試用的文本文件800M
          1.用sed解決,此法最易想,但也是最笨的一個,
          解決方法來自問題的提出者:
          sed -e '$d' input.file > output.file
          用time測試了一下,效率是相當的低!
          real    2m51.099s
          user    2m1.268s
          sys    0m4.260s
          2.用head解決,此法比sed有一個質的的提升,提升來自增大了緩存,不過依然沒有抓住問題的本質,還是做了不少無用功!解決方法來時cu上的熱心網友。
          head -n-1 input.file > output.file
          real    0m23.687s
          user    0m0.212s
          sys    0m4.668s
          3.用vim解決,此法很別處心裁,這應該是遇到這個問題的最先想到的一種。解決方法來自我加的unix like群里的一個叫石仔的管理員!
          vim + result
          dd
          這個沒測試,感覺效率和head法差不多,加載太慢!
          4.重量級要到場了,感謝cu版主的這個腳本,只能用四個字形容!五體投地!
          :|dd of=input.file seek=1 bs=$(($(find input.file -printf "%s")-$(tail -1 input.file|wc -c)))
          或者是
          :|dd of=input.file seek=1 bs=$(($(stat -c%s input.file)-$(tail -1 input.file|wc -c)))
          測試了一下!
          real    0m0.123s
          user    0m0.004s
          sys    0m0.012s
          5.感覺這個用c寫效率最高,但顯然,代碼也是最長的,我實現了代碼,
          測試了一下,
          real    0m0.002s
          user    0m0.000s
          sys    0m0.000s
          代碼如下:

          #include <stdio.h>
          #include <unistd.h>
          #include <fcntl.h>
          #include <sys/stat.h>
          #include <stdlib.h>

          #define GUESS_LINE_SIZE 80
          int get_line_size(char *ptr);

          int
          main(int argc, char *argv[])
          {
              char buf[GUESS_LINE_SIZE];
              int line_len, fd;
              struct stat stat_buf;
             
              fd = open(argv[1], O_RDWR);
              lstat(argv[1], &stat_buf);
              lseek(fd, -GUESS_LINE_SIZE, SEEK_END);
              read(fd, buf, GUESS_LINE_SIZE) ;
              line_len = get_line_size(buf);
              truncate(argv[1], stat_buf.st_size - line_len);
             
              exit(0);
          }

          int
          get_line_size(char *ptr)
          {
              int line_len = 0, i = GUESS_LINE_SIZE - 2;/*buf中的最后一個字符為'\n'*/
             
              while (*(ptr + i) != '\n') {
                  //printf("%c", *(ptr + i));

                  i--;
                  line_len++;
              }
              return line_len;
          }

          posted on 2010-04-21 18:45 xzc 閱讀(3292) 評論(2)  編輯  收藏 所屬分類: linux/unix

          評論:
          # re: 高效率刪除文本文件的最后一行 2010-04-21 18:48 | xzc
          :|dd of=input.file seek=1 bs=$(($(stat -c%s input.file)-$(tail -1 input.file|wc -c)))
          或者改為這樣更好理解:
          dd if=/dev/null of=input.file seek=1 bs=$(($(find input.file -printf "%s")-$(tail -1 input.file|wc -c)))
          也就是說:|的輸出是空字符串,而其作用正好與/dev/null相似。  回復  更多評論
            
          # re: 高效率刪除文本文件的最后一行 2010-04-22 11:02 | xzc
          文件行數
          cat DAPMmxdata004.20100421.201003.0001.771|wc -l  回復  更多評論
            
          主站蜘蛛池模板: 河东区| 卢氏县| 泰兴市| 临潭县| 武胜县| 宁武县| 余干县| 甘洛县| 左云县| 游戏| 胶南市| 灵石县| 深泽县| 贺兰县| 黄平县| 平原县| 甘孜| 霍城县| 尼玛县| 奉贤区| 乌鲁木齐县| 阿坝县| 宁波市| 南丹县| 融水| 平和县| 公安县| 叙永县| 固原市| 九龙城区| 九江县| 新密市| 上饶县| 郴州市| 军事| 大足县| 桂平市| 灵宝市| 乐安县| 旌德县| 巨鹿县|