Bash 将数据从一个源迁移到另一个源的脚本
我有一个.h文件,其中包含这种格式的数据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
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