2

これが欲しいのですが、sed ソリューションは良さそうですが、試してみると巨大​​な一時ファイルが作成されるようです。

テキストをファイルの先頭に追加する unix コマンド

28 GB のような大きな SQL ファイルがあり、ファイル システムにあまりスペースがなく、ファイルの先頭に 1 行追加したいだけです。ファイル容量を消費せずにこれを行うにはどうすればよいですか?

4

3 に答える 3

3

残念ながら、私がこれまでに見たすべての OS とファイル システムでは、通常、追加のように先頭に追加することはできません。データ量が基礎となるファイルシステムのブロックサイズの倍数であれば、ファイルシステムは効率的にそれを行うことができると主張するかもしれませんが、一般的にはそうではないため、実際にそのような機能を実装したものは知りません. したがって、おそらく、一時ファイルまたはコピーを使用するしか方法はありません。ただし、圧縮を使用して容量不足を多少緩和することはできますが、それには事前の作業が必要であり、最終的には適切ではない可能性があります。これらの行に沿ったもの:

1) gzip original_file.sql    # or bzip2 or whatever
2) create new_file.sql with data to be prepended
3) (cat new_file.sql; zcat original_file.sql.gz) | gzip > updated_file.sql.gz
4) zcat updated_file.sql.gz | less  # inspect the top of the file to make sure it looks right
5) rm original_file.sql.gz new_file.sql
6) gunzip updated_file.sql.gz # if necessary to have uncompressed text available - if not, just leave it compressed
于 2012-08-28T14:40:59.707 に答える
0

gcc でコンパイルします。

#include <stdio.h>
#include <string.h>
#include <malloc.h>

// Prepend size must be less than this value
#define bufSize 1024000

int main( int argc, char **argv )
{
    FILE *fil;
    unsigned char *smallBuf, *mainBuf;
    size_t sReadSize, mReadSize;
    long readPos = 0, writePos = 0;
    int appendSize;

    if( argc != 3 )
    {
        printf( "Usage: %s, <prepend_line> <file>\n", argv[0] );
        return 1;
    }

    sReadSize = appendSize = strlen( argv[1] ) + 1;

    smallBuf = (unsigned char *) malloc( appendSize );
    mainBuf = (unsigned char *) malloc( bufSize );
    if( !smallBuf || !mainBuf )
    {
        printf( "No memory\n" );
        return 1;
    }

    memcpy( smallBuf, argv[1], appendSize );
    smallBuf[ appendSize - 1 ] = '\n';

    fil = fopen( argv[2], "rb+" );
    if( !fil )
    {
        printf( "Cannot open file\n" );
        return 1;
    }

    while( 1 )
    {
        fseek( fil, readPos, 0 );
        readPos += mReadSize = fread( mainBuf, 1, bufSize, fil );

        fseek( fil, writePos, 0 );
        writePos += fwrite( smallBuf, 1, sReadSize, fil );

        if( mReadSize < bufSize )
        {
            if( mReadSize > 0 )
                fwrite( mainBuf, 1, mReadSize, fil );
            break;
        }

        fseek( fil, readPos, 0 );
        readPos += sReadSize = fread( smallBuf, 1, appendSize, fil );

        fseek( fil, writePos, 0 );
        writePos += fwrite( mainBuf, 1, mReadSize, fil );

        if( sReadSize < appendSize )
        {
            if( sReadSize > 0 )
                fwrite( smallBuf, 1, sReadSize, fil );
            break;
        }
    }

    fclose( fil );
    return 0;
}
于 2012-08-28T14:36:06.510 に答える
0

これには perl を使用できます。

perl -i -n -e 'print "xxx\n$_" if $.==1;print if $.!=1' your_file
于 2012-08-29T07:02:39.157 に答える