2013-08-06 55 views
13

tôi đề cập đến How can you concatenate two huge files with very little spare disk space?cắt bỏ 100MB đầu tiên của một tập tin trong Linux

Tôi ở giữa thực hiện như sau:

  1. Cấp phát một tập tin thưa thớt về quy mô cộng lại.
  2. Sao chép 100Mb từ cuối tệp thứ hai vào cuối tệp mới.
  3. Cắt ngắn 100Mb vào cuối tệp thứ hai
  4. Vòng 2 & 3 cho đến khi bạn hoàn tất tệp thứ hai (Với 2. sửa đổi đúng vị trí trong tệp đích).
  5. Làm 2 4 nhưng với tệp thứ nhất.

Tôi muốn biết liệu có ai ở đó có thể "cắt ngắn" một tệp nhất định trong linux không? Việc cắt ngắn theo kích thước tệp, ví dụ: nếu tệp là 10GB, tôi muốn cắt bớt 100MB đầu tiên của tệp và để tệp đó còn lại 9,9 GB. Bất cứ ai cũng có thể giúp đỡ trong việc này?

Cảm ơn

+0

Bạn đã google 'cắt xén tệp' của Linux chưa? Nó sẽ cung cấp cho bạn câu trả lời tốt! –

+0

có thể trùng lặp của [Truncate file ở phía trước] (http://stackoverflow.com/questions/706167/truncate-file-at-front) –

Trả lời

2

Vui lòng đọc một cuốn sách lập trình Linux tốt, ví dụ: Advanced Linux Programming.

Bạn cần phải sử dụng Linux kernelsyscalls, xem syscalls(2)

Đặc biệt truncate(2) (cho cả cắt ngắn, và cho việc mở rộng một tập tin thưa thớt trên các hệ thống tập tin hỗ trợ nó), và stat(2) để đáng chú ý là có được kích thước tập tin.

Không có cách nào (di động hoặc hệ thống tập tin trung lập) để xóa byte ngay từ đầu (hoặc ở giữa) của tệp, bạn chỉ có thể cắt bớt một tệp ở cuối tệp.

+0

có, đó chính xác là vấn đề của tôi. Dù sao, theo như tôi biết, cắt ngắn trong linux chỉ cắt ngắn đến một kích thước tập tin cố định. ví dụ: nếu bạn muốn kích thước tệp của mình là 4KB, bạn chỉ cần thực hiện 'truncate -s 4k filename.txt'. Những gì tôi muốn là để có tập tin của tôi giảm đầu hoặc đuôi của nó bằng 100MB. Điều đó có thể đạt được không? – CheeHow

5

Việc cắt đầu tệp là không thể với hầu hết các hệ thống tệp và không có API chung để thực hiện; ví dụ hàm truncate chỉ sửa đổi kết thúc của một tệp.

Mặc dù vậy, bạn vẫn có thể thực hiện với một số hệ thống tệp. Ví dụ như hệ thống tập tin ext4 thời gian gần đây có một ioctl mà bạn có thể tìm thấy hữu ích: http://lwn.net/Articles/556136/

+0

OP đề cập đến cắt xén * ở cuối tệp * trong phần câu hỏi –

+0

Có, và cả phần bắt đầu. – Joni

+0

mặc dù không có giải pháp rõ ràng, những gì trong tâm trí của tôi bây giờ chỉ là sử dụng lệnh 'truncate' để cắt ngắn đuôi tệp bằng cách lấy kích thước của tệp trừ đi 100MB. Cảm ơn đề xuất mặc dù ... – CheeHow

13

trả lời, bây giờ điều này là thực tế với Linux kernel v3.15 (ext4/xfs)

Đọc ở đây http://man7.org/linux/man-pages/man2/fallocate.2.html

Mã thử nghiệm

#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

Nếu bạn có thể làm việc với các dòng ASCII chứ không phải byte, thì việc xóa các dòng đầu tiên của tệp là dễ dàng. Ví dụ: để xóa 100 dòng đầu tiên:

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

dòng khác với kích thước. – user2284570

0

Đây là câu hỏi khá cũ lúc này, nhưng đây là câu hỏi của tôi về nó.Trừ các yêu cầu cho nó được thực hiện với không gian hạn chế có sẵn, tôi sẽ sử dụng một cái gì đó tương tự như sau để cắt ngắn 100MB đầu tiên của một tập tin:

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

Giải thích:

  • này kết quả đầu ra cuối cùng nn byte của tệp (đuôi - byte).
  • Số byte trong tệp đến đầu ra được tính bằng kích thước của tệp (wc -c < logfile.log) trừ 100Mb (expr $ (...) - 104857600). Điều này sẽ khiến chúng tôi nhỏ hơn 100Mb so với kích thước của tệp để lấy đuôi (ví dụ: 9.9Gb)
  • Sau đó, đầu ra này sẽ xuất ra tệp tạm thời và sau đó chuyển về tên tệp ban đầu để thoát tệp bị cắt bớt.
-1

loại bỏ tất cả nhưng 10000 dòng cuối cùng từ một tập tin

sed -i 1, $ (($ (wc -l < path/to/file) -10.000)) d path/to/file

+0

câu hỏi dựa trên kích thước tệp, không phải số lượng dòng –