Perl 基于另一个文件的索引,是否有更好的实现从一个文件提取多行文本结构?

Perl 基于另一个文件的索引,是否有更好的实现从一个文件提取多行文本结构?,perl,Perl,我有两个文件。一个是从数据库转储的表创建字符串文件,另一个是表名,前缀为“prompt”,后缀为“…”。如下: 文件A(索引): 文件B(转储): 我已经编写了一个perl实现,但我认为它太难看,效率太低。有没有更好的方法来改善这一点 我的代码:(根据Richard和lilydjwg的建议重写)(最新版本) #/usr/bin/perl 使用5.016; 我的(%hash,$cont); 打开,大概是你不喜欢的重复阅读 So-读取创建表文件一次,检查: CREATE TABLE "KS"."(\

我有两个文件。一个是从数据库转储的表创建字符串文件,另一个是表名,前缀为“prompt”,后缀为“…”。如下: 文件A(索引):

文件B(转储):

我已经编写了一个perl实现,但我认为它太难看,效率太低。有没有更好的方法来改善这一点

我的代码:(根据Richard和lilydjwg的建议重写)(最新版本)

#/usr/bin/perl
使用5.016;
我的(%hash,$cont);

打开,大概是你不喜欢的重复阅读

So-读取创建表文件一次,检查:

CREATE TABLE "KS"."(\w+)"
然后,您可以建立表定义,直到下一个创建表时为止,此时您将表定义放入由表名键入的哈希中

然后,阅读提示并从散列中逐个获取定义,然后将其打印出来

或者,您可以将CREATETABLE文件读入单个字符串,然后搜索并替换表名部分,因为这就是您目前正在更改的全部内容。不过,第一种方法更灵活


编辑: 您可以通过以下方式使定义的内容更加清晰:

while ($line=<IN>) {
    chomp($line);
    if (/CREATE TABLE "KS"\."(\w+)"/ && $hash{lc $1}) {
        $line = ...
    }
    say $line;
}
while($line=){
chomp($line);
if(/CREATE TABLE“KS”\.“(\w+)/&&&$hash{lc$1}){
$line=。。。
}
比如说$line;
}

我也喜欢在我的while循环中使用一个显式变量,当我超过几行时。

可能是重复读取你不喜欢的

So-读取创建表文件一次,检查:

CREATE TABLE "KS"."(\w+)"
然后,您可以建立表定义,直到下一个创建表时为止,此时您将表定义放入由表名键入的哈希中

然后,阅读提示并从散列中逐个获取定义,然后将其打印出来

或者,您可以将CREATETABLE文件读入单个字符串,然后搜索并替换表名部分,因为这就是您目前正在更改的全部内容。不过,第一种方法更灵活


编辑: 您可以通过以下方式使定义的内容更加清晰:

while ($line=<IN>) {
    chomp($line);
    if (/CREATE TABLE "KS"\."(\w+)"/ && $hash{lc $1}) {
        $line = ...
    }
    say $line;
}
while($line=){
chomp($line);
if(/CREATE TABLE“KS”\.“(\w+)/&&&$hash{lc$1}){
$line=。。。
}
比如说$line;
}

我喜欢在我的while循环中使用一个显式变量,当我超过几行时。

文件a似乎相对较小。您可以从中读取并构建包含所有表名的集合(或类似集合)。然后读取并标识SQL转储文件,对于每个表创建语句,检查该表名是否在您的集合中

我不太懂Perl,但这段Python代码似乎是您想要的:

import sys

tableNames = {x[7:-3] for l in open(sys.argv[1]) if x.startswith('prompt ')}

for l in open(sys.argv[2]):
  if l.startswith('CREATE TABLE "KS"."'):
    name = l.split('"')[4].lower()
    if name in tableNames:
      print("prompt {0}...\nCreate table{0}(".format(name))
  print(l, end='')

文件A似乎相对较小。您可以从中读取并构建包含所有表名的集合(或类似集合)。然后读取并标识SQL转储文件,对于每个表创建语句,检查该表名是否在您的集合中

我不太懂Perl,但这段Python代码似乎是您想要的:

import sys

tableNames = {x[7:-3] for l in open(sys.argv[1]) if x.startswith('prompt ')}

for l in open(sys.argv[2]):
  if l.startswith('CREATE TABLE "KS"."'):
    name = l.split('"')[4].lower()
    if name in tableNames:
      print("prompt {0}...\nCreate table{0}(".format(name))
  print(l, end='')

非常感谢。我用哈希表重写了代码(参见我编辑的OP)。但在读取文件B以创建哈希表时,我仍然对控制流不太满意。Perl中有什么常见的实践吗?非常感谢。我用哈希表重写了代码(参见我编辑的OP)。但在读取文件B以创建哈希表时,我仍然对控制流不太满意。Perl中有什么常见的实践吗?在SQL转储文件上读取和识别的过程是如何进行的?您能详细解释一下吗?如果我没有错的话,它只会在“提示xxxxx”行之后打印出“创建表XXXXXX”行。身体部位(专栏定义等等)怎么样?@Lord_WayneY,哦,你也可以这样做。我会在一段时间内更新代码。虽然你的代码仍然有一个bug,但我想我已经抓住了你的想法。我还修改了我的代码,先读取文件A,这样它就可以构建一个更小的哈希表?您能详细解释一下吗?如果我没有错的话,它只会在“提示xxxxx”行之后打印出“创建表XXXXXX”行。身体部位(专栏定义等等)怎么样?@Lord_WayneY,哦,你也可以这样做。我会在一段时间内更新代码。虽然你的代码仍然有一个bug,但我想我已经抓住了你的想法。我还修改了我的代码,首先读取文件A,这样它就可以构建一个更小的哈希表。