Скрипт для переноса данных из одного источника в другой - PullRequest
3 голосов
/ 24 ноября 2010

У меня есть файл .h, среди прочего, содержащий данные в этом формате

struct X[]{
{"Field", "value1 value2 value"},
{"Field2", "value11 value12 value232"},
{"Field3", "x  y z"},
{"Field4", "a bbb s"},
{"Field5", "sfsd sdfdsf sdfs"};
/****************/
};

У меня есть текстовый файл, содержащий значения, которые я хочу заменить в файле .h новыми значениями

value1   Valuesdfdsf1  
value2   Value1dfsdf  
value3   Value1_another  
sfsd     sfsd_ewew   
sdfdsf   sdfdsf_ew 
sdfs     sfsd_new   

И полученный .h файл будет содержать замены из текстового файла выше. Все остальное остается прежним.

struct X[]{
    {"Field1", "value11 value12 value232"},
    {"Field2", "value11 value12 value232"},
    {"Field3", "x  y z"},
    {"Field4", "a bbb s"},
    {"Field5", "sfsd_ewew sdfdsf_ew sdfs_new"};
    /****************/
    };

Пожалуйста, помогите мне найти решение для его реализации с использованием инструментов Unix: awk, perl, bash, sed и т. Д.

Ответы [ 5 ]

3 голосов
/ 24 ноября 2010
cat junk/n2.txt | perl -e '{use File::Slurp; my @r = File::Slurp::read_file("junk/n.txt"); my %r = map {chomp; (split(/\s+/,$_))[0,1]} @r; while (<>) { unless (/^\s*{"/) {print $_; next;}; my ($pre,$values,$post) = ($_ =~ /^(\s*{"[^"]+", ")([^"]+)(".*)$/); my @new_values = map { exists $r{$_} ? $r{$_}:$_ } split(/\s+/,$values); print $pre . join(" ",@new_values) . $post . "\n"; }}'     

Результат:

struct X[]{
{"Field", "value1 Value1dfsdf value"},
{"Field2", "value11 value12 value232"},
{"Field3", "x y z"},
{"Field4", "a bbb s"},
{"Field5", "sfsd_ewew sdfdsf_ew sfsd_new"};
/****************/
};

Код не распутан:

use File::Slurp;
my @replacements = File::Slurp::read_file("junk/n.txt"); 
my %r = map {chomp; (split(/\s+/,$_))[0,1]} @replacements; 
while (<>) {
    unless (/^\s*{"/) {print $_; next;}
    my ($pre,$values,$post) = ($_ =~ /^(\s*{"[^"]+", ")([^"]+)(".*)$/); 
    my @new_values = map { exists $r{$_} ? $r{$_} : $_ } split(/\s+/, $values);
    print $pre . join(" ",@new_values) . $post . "\n";
}
2 голосов
/ 25 ноября 2010
#!/usr/bin/perl

use strict; use warnings;

# you need to populate %lookup from the text file
my %lookup = qw(
    value1   Valuesdfdsf1
    value2   Value1dfsdf
    value3   Value1_another
    sfsd     sfsd_ewew
    sdfdsf   sdfdsf_ew
    sdfs     sfsd_new
);

while ( my $line = <DATA> ) {
    if ( $line =~ /^struct \w+\Q[]/ ) {
        print $line;
        process_struct(\*DATA, \%lookup);
    }
    else {
        print $line;
    }
}

sub process_struct {
    my ($fh, $lookup) = @_;

    while (my $line = <$fh> ) {
        unless ( $line =~ /^{"(\w+)", "([^"]+)"}([,;])\s+/ ) {
            print $line;
            return;
        }
        my ($f, $v, $p) = ($1, $2, $3);
        $v =~ s/(\w+)/exists $lookup->{$1} ? $lookup->{$1} : $1/eg;
        printf qq|{"%s", "%s"}%s\n|, $f, $v, $p;
    }
    return;
}

__DATA__
struct X[]{
{"Field", "value1 value2 value"},
{"Field2", "value11 value12 value232"},
{"Field3", "x  y z"},
{"Field4", "a bbb s"},
{"Field5", "sfsd sdfdsf sdfs"};
/****************/
};
1 голос
/ 25 ноября 2010

Вот простая программа:

use strict;
use warnings;
use File::Copy;

use constant {
    OLD_HEADER_FILE   => "headerfile.h",
    NEW_HEADER_FILE   => "newheaderfile.h",
    DATA_TEXT_FILE    => "data.txt",
};

open (HEADER, "<", OLD_HEADER_FILE) or
die qq(Can't open file old header file ") . OLD_HEADER_FILE . qq(" for reading);

open (NEWHEADER, ">", NEW_HEADER_FILE) or
die qq(Can't open file new header file ") . NEW_HEADER_FILE . qq(" for writing);

open (DATA, "<", DATA_TEXT_FILE) or
die qq(Can't open file data file ") . DATA_TEXT_FILE . qq(" for reading); 

#
# Put Replacement Data in a Hash
#

my %dataHash;
while (my $line = <DATA>) {
    chomp($line);
    my ($key, $value) = split (/\s+/, $line);
    $dataHash{$key} = $value if ($key and $value);
}
close (DATA);

#
# NOW PARSE THOUGH HEADER
# 

while (my $line = <HEADER>) {
    chomp($line);
    if ($line =~ /^\s*\{"Field/) {
        foreach my $key (keys(%dataHash)) {
            $line =~ s/\b$key\b/$dataHash{$key}/g;
        }
    }
    print NEWHEADER "$line\n";
}

close (HEADER);
close (NEWHEADER);
copy(NEW_HEADER_FILE, OLD_HEADER_FILE) or
  die qq(Unable to replace ") . OLD_HEADER_FILE . qq(" with ") . NEW_HEADER_FILE . qq(");

Я мог бы сделать его более эффективным , используя map, но это усложняет понимание.

В основном:

  • Я открываю три файла: оригинальный заголовок, новый заголовок, который я строю, и файл данных
  • Сначала я помещаю свои данные в хеш, где текст замены заменяется исходным текстом. (Мог бы сделать это наоборот, если бы я хотел.
  • Затем я просматриваю каждую строку исходного заголовка. ** Если я вижу линию, которая выглядит как линия поля, я знаю, что мне, возможно, придется сделать замену. ** Для каждой записи в моем %dataHash я заменяю $key значением замены $dataHash{$key}. Я использую \b, чтобы отметить границы слова . Таким образом, field11 не подставляется, потому что я вижу field1 в этой строке. ** Теперь я записываю строку обратно в мой новый заголовочный файл. Если я ничего не заменил, я просто напишу оригинальную строку.
  • Как только я закончу, я копирую новый заголовок поверх старого файла заголовка.
0 голосов
/ 25 ноября 2010

Этот скрипт должен работать
keyval - это файл, содержащий пары значений ключей
filetoreplace - это файл, содержащийданные для изменения
Файл с именем изменен будет содержать изменения

#!/bin/sh
echo  

keylist=`cat keyval | awk '{ print $1}'`  


while read line   
do   

for i in $keylist  
do  


if echo $line | grep -wq $i; then  

    value=`grep -w $i keyval | awk '{print $2}'`  
    line=`echo $line | sed -e "s/$i/$value/g"`  
fi  

done  

echo $line >> changed  

done < filetoreplace
0 голосов
/ 25 ноября 2010

Это может быть довольно медленно, если ваши файлы большие.

gawk -F '[ \t]*|"' 'FNR == NR {repl[$1]=$2;next}{for (f=1;f<=NF;++f) for (r in repl) if ($f == r) $f=repl[r]; print} ' keyfile file.h
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...