Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用bash从bigfile中删除第一行_Bash_Shell_Unix - Fatal编程技术网

使用bash从bigfile中删除第一行

使用bash从bigfile中删除第一行,bash,shell,unix,Bash,Shell,Unix,我有一个文本文件,想删除第一行(标题),将没有标题的文件读入管道。这似乎是一个已经被回答了很多次的琐碎问题,但由于我面临的文件的大小,到目前为止我找到的解决方案都不起作用。对于我的测试运行,我使用了echo“$(tail-n+2“$FILE\u NAME”)”>“$FILE\u NAME”,但是使用更大的文件运行此操作会导致以下错误:bash:xrealloc:无法分配18446744071562067968字节(已分配1679360字节)是否有任何方法可以编辑该文件?将它们加载到内存无法工作,

我有一个文本文件,想删除第一行(标题),将没有标题的文件读入管道。这似乎是一个已经被回答了很多次的琐碎问题,但由于我面临的文件的大小,到目前为止我找到的解决方案都不起作用。对于我的测试运行,我使用了
echo“$(tail-n+2“$FILE\u NAME”)”>“$FILE\u NAME”
,但是使用更大的文件运行此操作会导致以下错误:
bash:xrealloc:无法分配18446744071562067968字节(已分配1679360字节)
是否有任何方法可以编辑该文件?将它们加载到内存无法工作,我的一些文件大小高达400GB。
谢谢你的帮助

您可以使用如下代码:

awk 'NR!=1 {print}' input_file >output file
这将发送到除第一行以外的所有输出文件。您可以使用此构造执行操作:

awk 'NR!=1 {print}' input_file|operation1|operation2...
以这种方式更改命令可以完成以下工作:

tail -n +2 "$FILE_NAME" > "${FILE_NAME}.new"

这将需要两倍的磁盘空间

对于此操作来说,Tail相当有效

问题在于您想要覆盖原始文件

使用bash
“$()”
延迟创建输出文件意味着bash必须将内容保存在内存中,因此会出现错误消息。对于大文件,最好将输出写入临时文件,然后使用
mv
将其移到原始文件上

当sed在覆盖模式下使用时,它正好做到这一点(对于超过几行的任何内容)

它使用verysimple脚本
1d
运行
sed
,该脚本拾取第一行(选择符
1
并删除它(命令
d
)。由于使用了就地选项
-i
,您的文件将被覆盖,而无需使用中间文件


即使您不需要处理中间文件,
sed
在内部使用自己的中间文件。在这个操作过程中,您的磁盘使用量将增加到文件大小的两倍。

我只想解决问题的“就地编辑文件”部分,尽管看起来这并不是您真正想要的。您会发现许多解决方案描述了声称可以进行就地编辑的功能,但通常这些解决方案根本不会编辑文件。相反,它们写入临时文件,然后用临时文件覆盖原始文件。(例如,
sed-in-place
是一种常见的解决方案,它可以写入临时文件)。在适当的位置编辑文件几乎是你永远不想做的事情,因为改变文件是危险的。诚然,如果您认为您想在适当的位置编辑一个文件,请认真考虑并假设您错了。然而,如果出于某种原因,你真的需要这样做,那么只做可能是最安全的:

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

FILE * xfopen(const char *path, const char *mode);
int is_regular(int, const char *);

int
main(int argc, char **argv)
{
        const char *rpath = argc > 1 ? argv[1] : "stdin";
        const char *wpath = argc > 1 ? argv[1] : "stdout";
        FILE *fr = argc > 1 ? xfopen(rpath, "r") : stdin;
        FILE *fw = argc > 1 ? xfopen(wpath, "r+") : stdout;
        char buf[BUFSIZ];
        int c;
        size_t rc;
        off_t length = 0;

        /* Discard the first line */
        while( (c = getc(fr)) != EOF && c != '\n' ) {
                ;
        }
        if( c != EOF) while( (rc = fread(buf, 1, BUFSIZ, fr)) > 0) {
                size_t wc;
                wc = fwrite(buf, 1, rc, fw);
                length += wc;
                if( wc!= rc) {
                        break;
                }
        }
        if( fclose(fr) ) {
                err(EXIT_FAILURE, "%s", rpath);
        }
        if( is_regular(fileno(fw), wpath) && ftruncate(fileno(fw), length)) {
                err(EXIT_FAILURE, "%s", wpath);
        }
        if( fclose(fw)) {
                err(EXIT_FAILURE, "%s", wpath);
        }
        return EXIT_SUCCESS;
}

FILE *
xfopen(const char *path, const char *mode)
{
        FILE *fp = fopen(path, mode);
        if( fp == NULL ) {
                perror(path);
                exit(EXIT_FAILURE);
        }
        return fp;
}

int
is_regular(int fd, const char *name)
{
        struct stat s;
        if( fstat(fd, &s) == -1 ) {
                perror(name);
                exit(EXIT_FAILURE);
        }
        return !!(s.st_mode & S_IFREG);
}
#包括
#包括
#包括
#包括
#包括
文件*xfopen(常量字符*路径,常量字符*模式);
int是正则的(int,const char*);
int
主(内部argc,字符**argv)
{
常量char*rpath=argc>1?argv[1]:“stdin”;
常量char*wpath=argc>1?argv[1]:“stdout”;
文件*fr=argc>1?xfopen(rpath,“r”):stdin;
文件*fw=argc>1?xfopen(wpath,“r+”):标准输出;
char buf[BUFSIZ];
INTC;
尺寸(rc);;
关断长度=0;
/*丢弃第一行*/
而((c=getc(fr))!=EOF&&c!='\n'){
;
}
如果(c!=EOF)而((rc=fread(buf,1,BUFSIZ,fr))>0){
尺寸t wc;
wc=fwrite(buf,1,rc,fw);
长度+=wc;
如果(wc!=rc){
打破
}
}
如果(fclose(fr)){
错误(退出失败,“%s”,rpath);
}
if(是规则的(文件号(fw),wpath)和&ftruncate(文件号(fw),长度)){
错误(退出失败,“%s”,wpath);
}
如果(fclose(fw)){
错误(退出失败,“%s”,wpath);
}
返回退出成功;
}
文件*
xfopen(常量字符*路径,常量字符*模式)
{
FILE*fp=fopen(路径、模式);
如果(fp==NULL){
佩罗尔(路径);
退出(退出失败);
}
返回fp;
}
int
是正则的(int-fd,const-char*name)
{
结构统计;
如果(fstat(fd,&s)=-1){
佩罗尔(姓名);
退出(退出失败);
}
return!!(s.st\u mode&s\u IFREG);
}

通过显式,很明显,您很容易丢失文件中的数据。但是,如果您想避免将整个文件读入内存,或者避免在某些备份介质上同时拥有两个副本,那么就无法避免这样做,任何掩盖这种风险的解决方案都是在愚弄您。因此,明确表达并了解危险所在是正确的做法。

我并不感到惊讶。将
tail
的输出作为
echo
的参数传递。这里远远超过了最大参数长度。实际上,您不需要echo,只需执行
$tail-n+2 file>file.new即可。注意,您必须复制文件,不能将管道插入同一个文件,因此此
$tail-n+2文件>文件将不起作用!通常,最好将磁盘格式设计为不需要这种操作,至少如果您经常这样做的话。例如,如果您正在构建队列,使推送和弹出高效的一种方法是将内容拆分为两个文件,一个正向文件和一个反向文件,这样您可以有效地缩短反向文件以删除顶部的内容,或者延长正向文件以添加底部的内容;然后,你所需要做的就是在必要时安排在它们之间移动内容。如果保证不需要超过固定存储量,那么使用环形缓冲区并将指针移动到其中就更容易了。
#include <err.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>

FILE * xfopen(const char *path, const char *mode);
int is_regular(int, const char *);

int
main(int argc, char **argv)
{
        const char *rpath = argc > 1 ? argv[1] : "stdin";
        const char *wpath = argc > 1 ? argv[1] : "stdout";
        FILE *fr = argc > 1 ? xfopen(rpath, "r") : stdin;
        FILE *fw = argc > 1 ? xfopen(wpath, "r+") : stdout;
        char buf[BUFSIZ];
        int c;
        size_t rc;
        off_t length = 0;

        /* Discard the first line */
        while( (c = getc(fr)) != EOF && c != '\n' ) {
                ;
        }
        if( c != EOF) while( (rc = fread(buf, 1, BUFSIZ, fr)) > 0) {
                size_t wc;
                wc = fwrite(buf, 1, rc, fw);
                length += wc;
                if( wc!= rc) {
                        break;
                }
        }
        if( fclose(fr) ) {
                err(EXIT_FAILURE, "%s", rpath);
        }
        if( is_regular(fileno(fw), wpath) && ftruncate(fileno(fw), length)) {
                err(EXIT_FAILURE, "%s", wpath);
        }
        if( fclose(fw)) {
                err(EXIT_FAILURE, "%s", wpath);
        }
        return EXIT_SUCCESS;
}

FILE *
xfopen(const char *path, const char *mode)
{
        FILE *fp = fopen(path, mode);
        if( fp == NULL ) {
                perror(path);
                exit(EXIT_FAILURE);
        }
        return fp;
}

int
is_regular(int fd, const char *name)
{
        struct stat s;
        if( fstat(fd, &s) == -1 ) {
                perror(name);
                exit(EXIT_FAILURE);
        }
        return !!(s.st_mode & S_IFREG);
}