Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.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
使用perl合并两个文件,将原始文件的副本保留在其他文件中_Perl_Merge - Fatal编程技术网

使用perl合并两个文件,将原始文件的副本保留在其他文件中

使用perl合并两个文件,将原始文件的副本保留在其他文件中,perl,merge,Perl,Merge,我必须创建像A.ini和B.ini这样的文件,我想在A.ini中合并这两个文件 examples of files: A.ini:: a=123 b=xyx c=434 B.ini contains: a=abc m=shank n=paul my output in files A.ini should be like a=123abc b=xyx c=434 m=shank n=paul 我想用perl语言完成这个合并,我想把旧A.ini文件的副本保存在其他地方,以便使用旧副本,怎

我必须创建像A.ini和B.ini这样的文件,我想在A.ini中合并这两个文件

examples of files:
A.ini::

a=123
b=xyx
c=434

B.ini contains:
a=abc
m=shank
n=paul

my output in files A.ini should be like

a=123abc
b=xyx
c=434
m=shank
n=paul
我想用perl语言完成这个合并,我想把旧A.ini文件的副本保存在其他地方,以便使用旧副本,怎么样:

#!/usr/bin/perl
use strict;
use warnings;

my %out;
my $file = 'path/to/A.ini';
open my $fh, '<', $file or die "unable to open '$file' for reading: $!";
while(<$fh>) {
    chomp;
    my ($key, $val) = split /=/;
    $out{$key} = $val;
}
close $fh;

$file = 'path/to/B.ini';
open my $fh, '<', $file or die "unable to open '$file' for reading: $!";
while(<$fh>) {
    chomp;
    my ($key, $val) = split /=/;
    if (exists $out{$key}) {
        $out{$key} .= $val;
    } else {
        $out{$key} = $val;
    }
}
close $fh;

$file = 'path/to/A.ini';
open my $fh, '>', $file or die "unable to open '$file' for writing: $!";
foreach(keys %out) {
    print $fh $_,'=',$out{$_},"\n";
}
close $fh;
#/usr/bin/perl
严格使用;
使用警告;
我的%out;
my$file='path/to/A.ini';
打开我的$fh、、$file或die“无法打开$file进行写入:$!”;
foreach(键%out){
打印$fh$\'=',$out{$\},“\n”;
}
收盘价$fh;

命令行变体:

perl -lne '
($a, $b) = split /=/;
$v{$a} = $v{$a} ? $v{$a} . $b : $_;
END {
  print $v{$_} for sort keys %v
}' A.ini B.ini >NEW.ini

要合并的两个文件可以在一次过程中读取,不需要作为单独的源文件处理。这允许使用
读取命令行上作为参数传递的所有文件

保留
a.ini
的备份副本只需在将合并数据写入同名新文件之前对其进行重命名即可

此程序似乎可以执行您需要的操作

use strict;
use warnings;

my $file_a = $ARGV[0];

my (@keys, %values);

while (<>) {
  if (/\A\s*(.+?)\s*=\s*(.+?)\s*\z/) {
    push @keys, $1 unless exists $values{$1};
    $values{$1} .= $2;
  }
}

rename $file_a, "$file_a.bak" or die qq(Unable to rename "$file_a": $!);
open my $fh, '>', $file_a or die qq(Unable to open "$file_a" for output: $!);
printf $fh "%s=%s\n", $_, $values{$_} for @keys;

请在发布问题之前投入您的努力…未测试。。。或者您将使用$file_a进行读取,而不是在上使用stdin。为什么你的正则表达式如此复杂?为什么不直接吃1美元和2美元呢?而且\z应该是\z。正则表达式也会因为错误而大量回溯。匹配,应为[^=]。输出键顺序也取决于A和B的输入顺序,但这并不明确。在读取所有文件的整个过程中,它对主文件的大文件也没有弹性。不过,还是很紧凑。@PhilH:我已经测试了我的代码,但我不理解你的大部分评论
读取
ARGV
,只要
@ARGV
不是空的,就可以正常工作;您不能
chomp
$1
$2
,而且它只会从末尾删除换行符
\z
应该是
\z
,而不是
\z
;我不在乎回溯这么长的字符串;从代码中可以清楚地看出,要修改的文件是第一个参数;我不希望看到GB大小的ini文件。
a=123abc
b=xyx
c=434
m=shank
n=paul