0

我什至不确定这是否可能,但我确实希望它是可能的。

我在文件 backup.xml 中有这行 766 次:

*** Hosting Services

list.txt然后我有一个包含 766 行的文件。我需要***用 766 行中的每一行的内容替换list.txt- 如果可能的话,它需要以相同的顺序排列。

提前感谢您的帮助!

4

4 回答 4

1

主意:

loop over the lines of the B(ackup file)
  if you (F)ind a B-line to change
     read the next line of the L(ist file)
     change
  print the line to R(result file)

计划:

read_open B
read_open L
write_open R
while (line from B)
  if (F) {
    read replacemment from L
    change line
  }
  print line to R
}
close R, L, B

实现一(read_open,循环,看B):

use strict;
use warnings;
use English qw(-no_match_vars);

my $bfn = '../data/AA-backup-xml';
open my $bfh, '<', $bfn or die "Can't read open '$bfn': $OS_ERROR";
while (my $line = <$bfh>) {
        print $line;
}
close $bfh or die "Can't read close '$bfn': $OS_ERROR";

输出:

perl 01.pl
whatever
whatever
*** Hosting Services
whatever
whatever
whatever
*** Hosting Services
whatever
whatever
*** Hosting Services
whatever
whatever
whatever
*** Hosting Services

实现二(读/写,F,替换,第一个结果):

use Modern::Perl;
use English qw(-no_match_vars);

my $bfn = '../data/AA-backup-xml';
open my $bfh, '<', $bfn or die "Can't read open '$bfn': $OS_ERROR";
my $lfn = '../data/AA-list.txt';
open my $lfh, '<', $lfn or die "Can't read open '$lfn': $OS_ERROR";
my $rfn = '../data/AA-result';
open my $rfh, '>', $rfn or die "Can't write open 'rlfn': $OS_ERROR";
while (my $line = <$bfh>) {
    if ($line =~ /\*{3}/) {
        my $rpl = <$lfh>;
        $rpl = substr($rpl, 0, 3);
        $line =~ s/\*{3}/$rpl/;
    }
    print $rfh $line;
}
close $rfh or die "Can't write close '$rfn': $OS_ERROR";
close $lfh or die "Can't read close '$lfn': $OS_ERROR";
close $bfh or die "Can't read close '$bfn': $OS_ERROR";

输出:

type ..\data\AA-result
whatever
whatever
001 Hosting Services
whatever
whatever
whatever
002 Hosting Services
whatever
whatever
003 Hosting Services
whatever
whatever
whatever
004 Hosting Services

如果这对您“不起作用”(也许我猜错了 B 的结构或 F 策略过于幼稚),那么请发布 B、L 和 R 的代表性样本。

于 2013-05-24T08:41:37.287 回答
0
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET /a linenum=0
(
FOR /f "delims=" %%i IN ('findstr /n "$" ^<backup.xml') DO (
 SET "line=%%i"
 SET "line=!line:*:=!"
 IF DEFINED line (
  IF "!line!"=="*** Hosting Services" (
   SET /a linenum+=1
   FOR /f "tokens=1*delims=:" %%r IN ('findstr /n "$" ^<list.txt') DO (
    IF !linenum!==%%r (ECHO(%%s Hosting Services) 
   )
  ) ELSE (ECHO(!line!)
 ) ELSE (ECHO()
)
)>new.xml

GOTO :eof

IIUC,这应该用 替换每一"*** Hosting Services"backup.xmlline corresponding from list.txt *** Hosting Services创建一个新文件new.xml

于 2013-05-24T11:54:54.720 回答
0

您可以通过Tie::File将文件表示为数组来查看/修改文件,即:

use strict; 
use warnings;
use Tie::File;

tie my @ra1, 'Tie::File', "test.txt" or die; #*** Hosting Services
tie my @ra2, 'Tie::File', "test1.txt" or die; #stuff you want to replace *** with

#assumes equal length
for (my $i=0; $i <= $#ra1; $i++)
{
    my $temp=$ra2[$i];
    $ra1[$i]=~s/(\*{3})/$temp/; 
}

untie @ra1;
untie @ra2;

上面的代码替换***为列表文件的相应行。通过编写$ra1[$i]=~s/(\*{3})/$temp/,我们直接更改了@ra1 所绑定的文件。

于 2013-05-24T06:37:42.377 回答
0

它在 awk 中非常简短和甜蜜:

awk '
    NR == FNR {list[FNR]=$0; next}
    /\*\*\* Hosting Services/ {sub(/\*\*\*/, list[++count])}
    {print}
' list.txt backup.xml > new_backup.xml

a2p把它变成

#!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
    if $running_under_some_shell;
            # this emulates #! processing on NIH machines.
            # (remove #! line above if indigestible)

eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
            # process any FOO=bar switches

$, = ' ';       # set output field separator
$\ = "\n";      # set output record separator

line: while (<>) {
    chomp;  # strip record separator
    if ($. == ($.-$FNRbase)) {
        $list{($.-$FNRbase)} = $_;
        next line;
    }
    if (/\*\*\* Hosting Services/) {
        ($s_ = '"'.($list{++$count}).'"') =~ s/&/\$&/g, s/\*\*\*/eval $s_/e;
    }
    print $_;
}
continue {
    $FNRbase = $. if eof;
}
于 2013-05-24T12:13:07.773 回答