每出现 n 次字符串就将文本文件保存到字段(列)

每出现 n 次字符串就将文本文件保存到字段(列)

我正在创建 Cisco 结构配置的 Excel 电子表格,并希望将格式直接导入字段/列中以供导入。

这是格式,当然还有修改后的信息:

zone name Zone1_HOSTNAME01 vsan XXX
  fcalias name STORAGEPORT_0 vsan XXX
    pwwn xx:xx:xx:xx:xx

  fcalias name STORAGEPORT_1 vsan XXX
    pwwn xx:xx:xx:xx:xx

  fcalias name STORAGEPORT_2 vsan XXX
    pwwn xx:xx:xx:xx:xx

zone name Zone2_HOSTNAME02 vsan XXX
  fcalias name STORAGEPORT_3 vsan XXX
    pwwn xx:xx:xx:xx:xx

  fcalias name STORAGEPORT_4 vsan XXX
    pwwn xx:xx:xx:xx:xx

  fcalias name HOSTNAME02 vsan XXX
    pwwn xx:xx:xx:xx:xx

所以我想要做的是将区域名称 ZONE NAME 中的所有内容都包含到 1 个字段中的“vsan”空间,然后直到下一次出现带有“区域名称”的行开头,将每个字符串放入其自己的字段中然后我可以使用分隔符“剪切”以获得我想要的内容。所以本质上我最终想要的是:

"zone name Zone1_HOSTNAME01" "vsan" "XXX" "fcalias name" "STORAGEPORT_0 vsan XXX" "pwwn xx:xx:xx:xx:xx" "fcalias name" "STORAGEPORT_1 vsan XXX" "pwwn xx:xx:xx:xx:xx" "fcalias name" "STORAGEPORT_2 vsan XXX" "pwwn xx:xx:xx:xx:xx"

或类似的东西。每个空白都可以在它自己的字段中,因为之后我可以更容易地操作列。

该文本文件有 800 多行,有些可能更大,但目前还不清楚。最大的问题是,以“区域名称....”开头的初始行后面的文本可能会有所不同,所以我只需将它们翻译成它们自己的字段,而不管接下来是什么。

答案1

以下perl脚本以制表符分隔格式输出输入文件 ( markizy.txt),因为字段内有空格。

#!/usr/bin/perl

while(<>) {
  chomp;
  s/ +(vsan|fcalias|pwwn) */\t$1 /g ;
  s/ +\t/\t/;

  if ($. > 1 && m/^zone name/) {
    print $l,"\n";
    $l = $_;
  } elsif (eof) {
    $l .= $_;
    print $l,"\n";
  } else {
    $l .= $_;
  };
};

perl内置变量是当前行号,因此当位于输入的第一行时,$.脚本会避免打印(空行) 。有关此变量和许多其他变量(及其冗长的别名,例如for )的详细信息,zone name请参阅 参考资料。man perlvar$INPUT_LINE_NUMBER$.

将其保存到文件中,使用 使其可执行chmod +x,然后运行它。例如,cat -T显示选项卡 ( ^I):

$ ./markizy.pl markizy.txt  | cat -T
zone name Zone1_HOSTNAME01^Ivsan XXX^Ifcalias name STORAGEPORT_0^Ivsan XXX^Ipwwn xx:xx:xx:xx:xx^Ifcalias name STORAGEPORT_1^Ivsan XXX^Ipwwn xx:xx:xx:xx:xx^Ifcalias name STORAGEPORT_2^Ivsan XXX^Ipwwn xx:xx:xx:xx:xx
zone name Zone2_HOSTNAME02^Ivsan XXX^Ifcalias name STORAGEPORT_3^Ivsan XXX^Ipwwn xx:xx:xx:xx:xx^Ifcalias name STORAGEPORT_4^Ivsan XXX^Ipwwn xx:xx:xx:xx:xx^Ifcalias name HOSTNAME02^Ivsan XXX^Ipwwn xx:xx:xx:xx:xx

管道 tocat -T只是向您显示输出具有制表符分隔的字段(因为它们看起来与空格没有太大不同,否则)。实际运行时不要使用它,只需重定向到文件。 Excel(或gnumericLibre Office Calc或几乎任何其他电子表格)导入制表符分隔的文本文件应该没有困难 - 几乎从我记事起,它就一直是标准功能。

真正运行它:

./markizy.pl markizy.txt > markizy.csv

您可能必须告诉 Excel,导入时数据是制表符分隔的而不是逗号分隔的,否则它可能能够检测到该事实。

或者,如果您绝对确定没有任何数据字段将包含逗号,请将\t脚本中的所有 s 替换为逗号,这样您就可以用逗号分隔了。

答案2

从长远来看,在 Excel 中完成整个工作可能会更容易。我将您的示例剪切并粘贴到一个文本文件中,然后在 Excel 中打开它并得到以下内容:

在此输入图像描述

从那里,您可以使用全局搜索和替换命令进行您可能想要的任何修改。

答案3

很明显,某些字段可以省略,因为这些字段将在我导入排序数据后在 Excel 中创建的字符串中得到考虑。我确信有更好的选择,但这会占用我的所有输出,将所有值按顺序放在新行上,然后删除 vsan|pwwn|'zone name'|fcalias 的非必需字段,然后给我留下只是区域和成员别名以及 pwwn 条目。由于所有区域都以大写 Z 开头,这也使其变得更简单。

我在单行中使用的代码是:

grep -oP '\S+' switch01-zones-20160711 | grep -Ev 'name|vsan|^01|^02|fcalias|pwwn|zone' | awk '{printf "%s%s", (/^Zone/?rs:FS), $0; rs=RS} END{print ""}' >to-import.csv

这给我留下了每个区域的一个很好的单行以及连接的 www 设备的成员别名,并将其导入到 Excel 中以进行字符串构建,所有这些都在短时间内完成。

相关内容