Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.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 将数据从一个源迁移到另一个源的脚本_Bash_Perl_Sed_Scripting - Fatal编程技术网

Bash 将数据从一个源迁移到另一个源的脚本

Bash 将数据从一个源迁移到另一个源的脚本,bash,perl,sed,scripting,Bash,Perl,Sed,Scripting,我有一个.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 Values

我有一个.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等

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"; }}'     
代码解开:

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";
}
使用File::Slurp;
my@replacements=File::Slurp::read_文件(“junk/n.txt”);
my%r=map{chomp;(split(/\s+/,$)[0,1]}@replacements;
而(){
除非(/^\s*{”/{print$u;;next;}
我的($pre,$values,$post)=($)=~/^(\s*{“[^”]+”,”([^”]+)(“*)$/);
my@new_values=map{exists$r{$}?$r{$}:$}拆分(/\s+/,$values);
打印$pre.join(“,@new_值)。$post.\n”;
}
#!/usr/bin/perl
使用严格;使用警告;
#您需要从文本文件中填充%lookup
我的%lookup=qw(
值1值SDFDSF1
值2值1DFSDF
值3值1_其他值
sfsd sfsd_EW
sdfdsf sdfdsf_ew
可持续发展基金财经事务及库务局新
);
while(我的$line=){
如果($line=~/^struct\w+\Q[]/){
打印$行;
进程结构(\*数据,\%查找);
}
否则{
打印$行;
}
}
子过程结构{
我的($fh,$lookup)=@;
while(我的$line=){
除非($line=~/^{(\w+),“([^”]+)”}([,;])\s+/){
打印$行;
返回;
}
我的($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;
}
返回;
}
__资料__
结构X[]{
{“字段”、“值1值2值”},
{“Field2”、“value11 value12 value232”},
{“字段3”,“x y z”},
{“Field4”,“a bbb s”},
{“字段5”、“sfsd sdfdsf sdfs”};
/****************/
};

以下是一个外观简单的程序:

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(");
使用严格;
使用警告;
使用文件::复制;
使用常数{
旧的头文件=>“headerfile.h”,
新建头文件=>“newheaderfile.h”,
数据\文本\文件=>“DATA.txt”,
};
打开(头文件“,”新头文件)或
死qq(无法打开文件新头文件”).new_header_file.qq(“用于写入);

打开(数据),如果文件很大,这可能会有点慢

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

gawk-F'[\t]*|“''FNR==NR{repl[$1]=$2;next}{for(F=1;F此脚本应该可以工作
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
!/bin/sh
回音
keylist=`cat keyval|awk'{print$1}`
读行时
做
对于$keylist中的i
做
如果echo$line | grep-wq$i;那么
value=`grep-w$i keyval | awk'{print$2}`
line=`echo$line | sed-e“s/$i/$value/g”`
fi
完成
echo$line>>已更改
完成<文件替换

字段-值对是否总是在同一行,值之间是否用单个空格分隔?空格/制表符,至少有一个空格是肯定的。第一行的值2是否应该替换为值1DFSDF?您是对的,它应该是。已修复。您的值[123]在您期望的结果示例中,似乎没有正确地替换。天哪,我讨厌Perl的外观。丑陋的力量!不过,我的学习列表中的下一个:)@Morlock—这不是Perl的外观。这是Perl one liner的外观—设计为在字符串上占用尽可能少的空间。以适当的Perl编码风格编写,上述代码中的绝大多数标点符号都消失了,并留下了实际可读的程序。唯一看起来仍然像编码过的片段是正则表达式在任何语言中都是100%的相同。我可以,但伙计,感恩节前一天就要休息了:)以后请休息一下,Perl标签上的人或我会乐意帮忙的。只是现在不需要:)谢谢您的另一种更容易的眼罩版本:)
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
#!/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