2013-08-06 47 views
13

我指的是How can you concatenate two huge files with very little spare disk space?截斷文件的第一個100MB在linux

我在執行下面的中間是:

  1. 分配的組合大小的稀疏文件。
  2. 從第二個文件的末尾複製100Mb到新文件的末尾。
  3. 截斷第二個文件末尾的100Mb
  4. 迴路2 & 3直到您完成第二個文件(將2.修改爲目標文件中的正確位置)。
  5. 做2 2 4但與第一個文件。

我想知道是否有人誰能夠「截斷」在Linux中給定的文件?截斷是按文件大小,例如,如果文件是10GB,我想截斷文件的前100MB,並保留9.9GB的文件。任何人都可以幫忙嗎?

謝謝

+0

你對'Linux文件truncate'有谷歌嗎?它會給你很好的答案! –

+0

[截斷文件在前面]的可能重複(http://stackoverflow.com/questions/706167/truncate-file-at-front) –

回答

2

請閱讀一本很好的Linux編程書籍,例如Advanced Linux Programming

您需要使用Linux kernelsyscalls,看到syscalls(2)

特別truncate(2)(無論是截斷,並且對支持它的文件系統稀疏文件擴展),以及stat(2)來特別是獲取文件大小。

沒有(便攜式或文件系統中立)方式從文件的開頭(或中間)刪除字節,只能在文件末尾截斷文件。

+0

是的,這正是我的問題所在。無論如何,據我所知,截斷在Linux中只截斷到一個固定的文件大小。例如,如果您希望文件大小爲4KB,則只需執行truncate -s 4k filename.txt即可。我想要的是讓我的文件的頭部或尾部減少100MB。這是可以實現的嗎? – CheeHow

5

對大多數文件系統來說,切除文件的開頭是不可能的,而且沒有通用的API來完成;例如truncate函數只能修改文件的結尾。

雖然您可以使用某些文件系統來完成此操作。例如,ext4文件系統最近買了,你會發現有用的IOCTL:http://lwn.net/Articles/556136/

+0

該OP提到截斷*在文件末尾*在問題主體 –

+0

是的,也是開始。 – Joni

+0

儘管目前還沒有明確的解決方案,但現在我想到的只是使用'truncate'命令通過將文件大小減去100MB來手動截斷文件的尾部。感謝您的建議,雖然... – CheeHow

13

回答,現在這是現實與Linux內核v3.15(的ext4/XFS)

這裏閱讀 http://man7.org/linux/man-pages/man2/fallocate.2.html

測試代碼

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <stdlib.h> 
#include <fcntl.h> 

#ifndef FALLOC_FL_COLLAPSE_RANGE 
#define FALLOC_FL_COLLAPSE_RANGE  0x08 
#endif 

int main(int argc, const char * argv[]) 
{ 
    int ret; 
    char * page = malloc(4096); 
    int fd = open("test.txt", O_CREAT | O_TRUNC | O_RDWR, 0644); 

    if (fd == -1) { 
     free(page); 
     return (-1); 
    } 

    // Page A 
    printf("Write page A\n"); 
    memset(page, 'A', 4096); 
    write(fd, page, 4096); 

    // Page B 
    printf("Write page B\n"); 
    memset(page, 'B', 4096); 
    write(fd, page, 4096); 

    // Remove page A 
    ret = fallocate(fd, FALLOC_FL_COLLAPSE_RANGE, 0, 4096); 
    printf("Page A should be removed, ret = %d\n", ret); 

    close(fd); 
    free(page); 

    return (0); 
} 
1

如果您可以使用ASCII行而不是字節,那麼刪除文件的前n行很容易。例如,要刪除前100行:

sed -i 1,100d /path/to/file 
+1

線是不同的大小。 – user2284570

0

這是一個相當古老的問題,但這是我的承擔。不包括要求它利用有限的空間進行可用,我會使用類似以下截斷文件的第一100MB:

$ tail --bytes=$(expr $(wc -c < logfile.log) - 104857600) logfile.log > logfile.log.tmp 
$ mv logfile.log.tmp logfile.log 

說明:

  • 此輸出最後NN文件的字節(尾部 - 字節)。
  • 要輸出的文件中的字節數按照文件大小(wc -c < logfile.log)減去100Mb(expr $(...) - 104857600)計算。這將使我們的文件大小小於100Mb(例如9.9Gb)
  • 然後將其輸出到臨時文件,然後移回到原始文件名以留下截斷的文件。
-1

刪除所有,但該文件中的最後10000線

sed的-i 1,$(($(WC -l <路徑/到/文件)-10000))d路徑/到/文件

+0

這個問題是基於文件大小,而不是行數 –