Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.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
Unix 将头插入文件_Unix_Header_Insert_Awk - Fatal编程技术网

Unix 将头插入文件

Unix 将头插入文件,unix,header,insert,awk,Unix,Header,Insert,Awk,我想听听您如何将标题行(一个文件中的所有行)插入到另一个文件(更大,几GB)中的说明。我更喜欢Unix/awk/sed方式来完成这项工作 # header I need to insert to another, they are in a file named "header". ##fileformat=VCFv4.0 ##fileDate=20090805 ##source=myImputationProgramV3.1 ##reference=1000GenomesPilot-NCB

我想听听您如何将标题行(一个文件中的所有行)插入到另一个文件(更大,几GB)中的说明。我更喜欢Unix/awk/sed方式来完成这项工作

# header I need to insert to another, they are in a file named "header".


##fileformat=VCFv4.0
##fileDate=20090805
##source=myImputationProgramV3.1
##reference=1000GenomesPilot-NCBI36
##phasing=partial
##INFO=<ID=NS,Number=1,Type=Integer,Description="Number of Samples With Data">
##INFO=<ID=DP,Number=1,Type=Integer,Description="Total Depth">
##INFO=<ID=AF,Number=.,Type=Float,Description="Allele Frequency">
##INFO=<ID=AA,Number=1,Type=String,Description="Ancestral Allele">
##INFO=<ID=DB,Number=0,Type=Flag,Description="dbSNP membership, build 129">
##INFO=<ID=H2,Number=0,Type=Flag,Description="HapMap2 membership">
##FILTER=<ID=q10,Description="Quality below 10">
##FILTER=<ID=s50,Description="Less than 50% of samples have data">
##FORMAT=<ID=GT,Number=1,Type=String,Description="Genotype">
##FORMAT=<ID=GQ,Number=1,Type=Integer,Description="Genotype Quality">
##FORMAT=<ID=DP,Number=1,Type=Integer,Description="Read Depth">
##FORMAT=<ID=HQ,Number=2,Type=Integer,Description="Haplotype Quality">
#CHROM POS     ID        REF ALT    QUAL FILTER INFO 
#头我需要插入另一个,它们位于名为“头”的文件中。
##fileformat=VCFv4.0
##fileDate=20090805
##来源=我的插补程序v3.1
##参考=1000GenomesPilot-NCBI36
##相位=部分
##信息=
##信息=
##信息=
##信息=
##信息=
##信息=
##滤器=
##滤器=
##格式=
##格式=
##格式=
##格式=
#色度位置ID参考高度质量过滤器信息
您可能更愿意将临时文件定位在与正在编辑的文件相同的文件系统上,但任何需要在文件前面插入数据的操作最终都会非常接近这一点。如果你打算每天整日都这样做,你可能会组装一些更光滑的东西,但节省的可能性很小(每个文件只有几分之一秒)

如果您确实必须使用
sed
,那么我想您可以使用:

header="/name/of/file/containing/header"
for file in "$@"
do
    sed -e "0r $header" "$file" > /tmp/xx.$$
    mv /tmp/xx.$$ "$file"
done
该命令读取第0行之后(第1行之前)的标题“after”的内容,然后所有其他内容都会原封不动地通过。但这并不像猫那样迅速

使用awk的类似构造为:

header="/name/of/file/containing/header"
for file in "$@"
do
    awk '{print}' "$header" "$file" > /tmp/xx.$$
    mv /tmp/xx.$$ "$file"
done
这只是在输出上打印每个输入行;同样,速度不如
cat


sed
awk
相比,
cat
还有一个优点
cat
即使大文件主要是二进制数据也能工作(它不知道文件的内容)。
sed
awk
都设计用于处理拆分成行的数据;虽然现代版本甚至可以很好地处理二进制数据,但这并不是它们的设计初衷

我用一个Perl脚本完成了这一切,因为我必须遍历目录树并以不同的方式处理各种文件类型。基本剧本是

#!perl -w
process_directory(".");

sub process_directory {
    my $dir = shift;
    opendir DIR, $dir or die "$dir: not a directory\n";
    my @files = readdir DIR;
    closedir DIR;
    foreach(@files) {
        next if(/^\./ or /bin/ or /obj/);  # ignore some directories
        if(-d "$dir/$_") {
            process_directory("$dir/$_");
        } else {
            fix_file("$dir/$_");
        }
    }
}

sub fix_file {
    my $file = shift;
    open SRC, $file or die "Can't open $file\n";
    my $file = "$file-f";
    open FIX, ">$fix" or die "Can't open $fix\n";
    print FIX <<EOT;
        -- Text to insert
EOT
    while(<SRC>) {
        print FIX;
    }
    close SRC;
    close FIX;
    my $oldfile = $file;
    $oldFile =~ s/(.*)\.\(\w+)$/$1-old.$2/;
    if(rename $file, $oldFile) {
        rename $fix, $file;
    }
}
#!perl-w
进程目录(“.”);
子进程目录{
我的$dir=shift;
opendir、$DIR或die“$DIR:不是目录\n”;
my@files=readdir;
closedir;
foreach(@files){
下一个if(/^\./或/bin/或/obj/);#忽略一些目录
如果(-d“$dir/$\”){
进程目录(“$dir/$”);
}否则{
修复文件(“$dir/$”);
}
}
}
子修复文件{
我的$file=shift;
打开SRC,$file或die“无法打开$file\n”;
my$file=“$file-f”;
打开修复程序“>$FIX”或die“无法打开$FIX\n”;

一路打印修复,在文件开头插入导致所有后续字节移位,这意味着所有文件块都可能被更改。这是一个很酷的答案。我从你的指导中学到了很多。非常感谢。@Jonathan,我还需要在现有的大文件中添加标题行。在我的情况下,标题行对应于数字存储在bash变量中的。如何使用
awk/sed
来执行此操作?我做了如下操作:
awk-v param1=“$param1”-v param2=“$param2”'开始{print“description1”;print param1“param2”;print“description2”}{print}test data>${tmpFile}
。在大于2GB的文件中,我遇到以下错误:
awk:无法打开test.data(值对于定义的数据类型来说太大)
。您对如何处理大文件有什么建议吗?@Javier:如果您的
awk
在处理大文件(>2GB)时遇到问题,那么可能是时候升级一些东西了-可能是
awk
。要替换所描述的参数,您需要做更多的工作。请参阅的答案以查看文件中变量的单向处理。@Jonathan,谢谢!我最近在
linux
().我使用的是
Ubuntu10.04 64位
,最近安装的
11.04 32位
。而
awk
使用的是
10.04
版本中的大文件(
>2GB
),我没有遇到任何问题。这似乎就是我出现这些问题的原因。你认为,可能是这样吗?我也在尝试发现
11.04 64位
版本有多稳定。@jianfeng.mao:“非常感谢”我刚刚开始学习Unix shell/sed/awk/perl来做生物信息学。我还没有测试你的脚本。但是,非常感谢你的好意。
#!perl -w
process_directory(".");

sub process_directory {
    my $dir = shift;
    opendir DIR, $dir or die "$dir: not a directory\n";
    my @files = readdir DIR;
    closedir DIR;
    foreach(@files) {
        next if(/^\./ or /bin/ or /obj/);  # ignore some directories
        if(-d "$dir/$_") {
            process_directory("$dir/$_");
        } else {
            fix_file("$dir/$_");
        }
    }
}

sub fix_file {
    my $file = shift;
    open SRC, $file or die "Can't open $file\n";
    my $file = "$file-f";
    open FIX, ">$fix" or die "Can't open $fix\n";
    print FIX <<EOT;
        -- Text to insert
EOT
    while(<SRC>) {
        print FIX;
    }
    close SRC;
    close FIX;
    my $oldfile = $file;
    $oldFile =~ s/(.*)\.\(\w+)$/$1-old.$2/;
    if(rename $file, $oldFile) {
        rename $fix, $file;
    }
}