вставить заголовок в файл - PullRequest
6 голосов
/ 12 мая 2011

Я хотел бы услышать ваши указания о том, как вставить строки заголовка (все строки в файле) в другой файл (более крупный, несколько ГБ).Я предпочитаю 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 

Ответы [ 2 ]

12 голосов
/ 12 мая 2011
header="/name/of/file/containing/header"
for file in "$@"
do
    cat "$header" "$file" > /tmp/xx.$$
    mv /tmp/xx.$$ "$file"
done

Вы можете предпочесть разместить временный файл в той же файловой системе, что и файл, который вы редактируете, но все, что требует вставки данных в начало файла, в конечном итоге будет работать очень близко к этому. Если вы собираетесь делать это весь день, каждый день вы можете собрать что-нибудь немного более приятное, но есть вероятность, что экономия будет крошечной (доли секунды на файл).

Если вы действительно, действительно должны использовать 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), а затем все остальное пропускается без изменений. Это не так быстро, как cat.

Аналогичная конструкция, использующая awk:

header="/name/of/file/containing/header"
for file in "$@"
do
    awk '{print}' "$header" "$file" > /tmp/xx.$$
    mv /tmp/xx.$$ "$file"
done

Это просто печатает каждую строку ввода на выходе; опять же, не так быстро, как cat.

Еще одно преимущество cat над sed или awk; cat будет работать, даже если большие файлы в основном представляют собой двоичные данные (это не учитывает содержимое файлов). И sed, и awk предназначены для обработки данных, разбитых на строки; хотя современные версии, вероятно, будут обрабатывать даже двоичные данные достаточно хорошо, это не то, для чего они предназначены.

1 голос
/ 12 мая 2011

Я сделал все это с помощью 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-хакер, так что это, вероятно, двойной плюс неоптимальный код Perl. Тем не менее, у меня это сработало!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...