如何使用 Perl 从文件中提取某些数据?
How to extract certain data using Perl from a file?
我有需要从文件中提取的数据,我现在需要的行是名称、位置和主机。这是提取物的例子。我将如何将这些行放入一个单独的文件中?我有原始文件和我想创建的新文件 input/output 文件,输出文件中包含数千个设备,它们的格式都与我的示例相同。
#!/usr/bin/perl
use strict;
use warnings;
use POSIX qw(strftime);
#names of files to be input output
my $inputfile = "/home/nmis/nmis_export.csv";
my $outputfile = "/home/nmis/nmis_data.csv";
open(INPUT,'<',$inputfile) or die $!;
open(OUTPUT, '>',$outputfile) or die $!;
my @data = <INPUT>;
close INPUT;
my $line="";
foreach $line (@data)
{
======样本提取=======
**"group" : "NMIS8",
"host" : "1.2.3.4",
"location" : "WATERLOO",
"max_msg_size" : 1472,
"max_repetitions" : 0,
"model" : "automatic",
"netType" : "lan",
"ping" : 1,
"polling_policy" : "default",
"port" : 161,
"rancid" : 0,
"roleType" : "access",
"serviceStatus" : "Production",
"services" : null,
"threshold" : 1,
"timezone" : 0,
"version" : "snmpv2c",
"webserver" : 0
},
"lastupdate" : 1616690858,
"name" : "test",
"overrides" : {}
},
{
"activated" : {
"NMIS" : 1
},
"addresses" : [],
"aliases" : [],
"configuration" : {
"Stratum" : 3,
"active" : 1,
"businessService" : "",
"calls" : 0,
"cbqos" : "none",
"collect" : 0,
"community" : "public",
"depend" : [
"N/A"
],
"group" : "NMIS8",
"host" : "1.2.3.5",
"location" : "WATERLOO",
"max_msg_size" : 1472,
"max_repetitions" : 0,
"model" : "automatic",
"netType" : "lan",
"ping" : 1,
"polling_policy" : "default",
"port" : 161,
"rancid" : 0,
"roleType" : "access",
"serviceStatus" : "Production",
"services" : null,
"threshold" : 1,
"timezone" : 0,
"version" : "snmpv2c",
"webserver" : 0
},
"lastupdate" : 1616690858,
"name" : "test2",
"overrides" : {}
},**
因为你有 JSON,你应该用 JSON 解析器解析它。 JSON::PP 是标准 Perl 发行版的一部分。如果你想要更快的东西,你可以从 CPAN 安装其他东西。
更新: 我在回答中加入了 link 到 JSON::PP。您是否遵循 link?如果这样做,您就会看到该模块的文档。这比我在 SO 的答案中包含的更多关于如何使用该模块的信息。
但您可能需要更多高级信息。文档是这样说的:
JSON::PP is a pure perl JSON decoder/encoder
但也许你不知道那是什么意思。所以这是一本入门书。
JSON是一种用于存储复杂数据结构的文本格式。该格式最初用于 Javascript(首字母缩写词代表“JavaScript Object Notation”),但现在它已成为几乎所有编程语言都使用的标准。
您很少想在程序中实际处理 JSON。 JSON 文档只是文本和操作,需要一些复杂的正则表达式。在处理 JSON 时,通常的做法是将 JSON“解码”为程序内部的数据结构。然后,您可以在(可选)将数据结构“编码”回 JSON 之前随意操作数据结构,以便将其写入输出文件(在您的情况下,您不需要这样做您希望输出为 CSV)。
所以 Perl JSON 库几乎只需要做两件事:
- 获取一些 JSON 文本并将其解码为 Perl 数据结构
- 采用 Perl 数据结构并将其编码为 JSON 文本
如果您查看 JSON::PP documentation,您会发现它包含两个函数,encode_json()
和 decode_json()
,它们执行我上面描述的操作。还有一个 OO 接口,但我们不要太快把事情复杂化。
所以你的程序现在需要有以下步骤:
- 从输入文件
读取JSON
- 将JSON解码为Perl数据结构
- 遍历 Perl 数据结构以提取您需要的项目
- 将所需的项目写入您的输出文件(Text::CSV 对此很有用
说了这么多,在我看来 确实是一个更好的主意。
我会用jq
for this not Perl. You just need to query a JSON document. That's what jq is for. You can see an example here
我创建的jq查询就是这个,
.[] | {name: .name, group: .configuration.group, location: .configuration.location}
这分解为
.[] # iterate over the array
| # create a filter to send it to
{ # that produces an object with the bellow key/values
.name,
group: .configuration.group,
location: .configuration.location
}
它提供了这样的输出,
{
"name": "test2",
"group": "NMIS8",
"location": "WATERLOO"
}
{
"name": "test2",
"group": "NMIS8",
"location": "WATERLOO"
}
您可以使用它来生成 csv
jq -R '.[] | [.name, .configuration.group, .configuration.location] | @csv' ./file.json
或者生成一个带有 header,
的 csv
jq -R '["name","group","location"], (.[] | [.name, .configuration.group, .configuration.location]) | @csv' ./file.json
您可以为此使用 JSON
发行版。一口气读取整个文件,将整个 JSON 字符串放入标量(而不是将其放入数组并对其进行迭代),然后简单地将字符串解码为 Perl 数据结构:
use warnings;
use strict;
use JSON;
my $file = 'file.json';
my $json_string;
{
local $/; # Locally reset line endings to nothing
open my $fh, '<', $file or die "Can't open file $file!: $!";
$json_string = <$fh>; # Slurp in the entire file
}
my $perl_data_structure = decode_json $json_string;
我有需要从文件中提取的数据,我现在需要的行是名称、位置和主机。这是提取物的例子。我将如何将这些行放入一个单独的文件中?我有原始文件和我想创建的新文件 input/output 文件,输出文件中包含数千个设备,它们的格式都与我的示例相同。
#!/usr/bin/perl
use strict;
use warnings;
use POSIX qw(strftime);
#names of files to be input output
my $inputfile = "/home/nmis/nmis_export.csv";
my $outputfile = "/home/nmis/nmis_data.csv";
open(INPUT,'<',$inputfile) or die $!;
open(OUTPUT, '>',$outputfile) or die $!;
my @data = <INPUT>;
close INPUT;
my $line="";
foreach $line (@data)
{
======样本提取=======
**"group" : "NMIS8",
"host" : "1.2.3.4",
"location" : "WATERLOO",
"max_msg_size" : 1472,
"max_repetitions" : 0,
"model" : "automatic",
"netType" : "lan",
"ping" : 1,
"polling_policy" : "default",
"port" : 161,
"rancid" : 0,
"roleType" : "access",
"serviceStatus" : "Production",
"services" : null,
"threshold" : 1,
"timezone" : 0,
"version" : "snmpv2c",
"webserver" : 0
},
"lastupdate" : 1616690858,
"name" : "test",
"overrides" : {}
},
{
"activated" : {
"NMIS" : 1
},
"addresses" : [],
"aliases" : [],
"configuration" : {
"Stratum" : 3,
"active" : 1,
"businessService" : "",
"calls" : 0,
"cbqos" : "none",
"collect" : 0,
"community" : "public",
"depend" : [
"N/A"
],
"group" : "NMIS8",
"host" : "1.2.3.5",
"location" : "WATERLOO",
"max_msg_size" : 1472,
"max_repetitions" : 0,
"model" : "automatic",
"netType" : "lan",
"ping" : 1,
"polling_policy" : "default",
"port" : 161,
"rancid" : 0,
"roleType" : "access",
"serviceStatus" : "Production",
"services" : null,
"threshold" : 1,
"timezone" : 0,
"version" : "snmpv2c",
"webserver" : 0
},
"lastupdate" : 1616690858,
"name" : "test2",
"overrides" : {}
},**
因为你有 JSON,你应该用 JSON 解析器解析它。 JSON::PP 是标准 Perl 发行版的一部分。如果你想要更快的东西,你可以从 CPAN 安装其他东西。
更新: 我在回答中加入了 link 到 JSON::PP。您是否遵循 link?如果这样做,您就会看到该模块的文档。这比我在 SO 的答案中包含的更多关于如何使用该模块的信息。
但您可能需要更多高级信息。文档是这样说的:
JSON::PP is a pure perl JSON decoder/encoder
但也许你不知道那是什么意思。所以这是一本入门书。
JSON是一种用于存储复杂数据结构的文本格式。该格式最初用于 Javascript(首字母缩写词代表“JavaScript Object Notation”),但现在它已成为几乎所有编程语言都使用的标准。
您很少想在程序中实际处理 JSON。 JSON 文档只是文本和操作,需要一些复杂的正则表达式。在处理 JSON 时,通常的做法是将 JSON“解码”为程序内部的数据结构。然后,您可以在(可选)将数据结构“编码”回 JSON 之前随意操作数据结构,以便将其写入输出文件(在您的情况下,您不需要这样做您希望输出为 CSV)。
所以 Perl JSON 库几乎只需要做两件事:
- 获取一些 JSON 文本并将其解码为 Perl 数据结构
- 采用 Perl 数据结构并将其编码为 JSON 文本
如果您查看 JSON::PP documentation,您会发现它包含两个函数,encode_json()
和 decode_json()
,它们执行我上面描述的操作。还有一个 OO 接口,但我们不要太快把事情复杂化。
所以你的程序现在需要有以下步骤:
- 从输入文件 读取JSON
- 将JSON解码为Perl数据结构
- 遍历 Perl 数据结构以提取您需要的项目
- 将所需的项目写入您的输出文件(Text::CSV 对此很有用
说了这么多,在我看来
我会用jq
for this not Perl. You just need to query a JSON document. That's what jq is for. You can see an example here
我创建的jq查询就是这个,
.[] | {name: .name, group: .configuration.group, location: .configuration.location}
这分解为
.[] # iterate over the array
| # create a filter to send it to
{ # that produces an object with the bellow key/values
.name,
group: .configuration.group,
location: .configuration.location
}
它提供了这样的输出,
{
"name": "test2",
"group": "NMIS8",
"location": "WATERLOO"
}
{
"name": "test2",
"group": "NMIS8",
"location": "WATERLOO"
}
您可以使用它来生成 csv
jq -R '.[] | [.name, .configuration.group, .configuration.location] | @csv' ./file.json
或者生成一个带有 header,
的 csvjq -R '["name","group","location"], (.[] | [.name, .configuration.group, .configuration.location]) | @csv' ./file.json
您可以为此使用 JSON
发行版。一口气读取整个文件,将整个 JSON 字符串放入标量(而不是将其放入数组并对其进行迭代),然后简单地将字符串解码为 Perl 数据结构:
use warnings;
use strict;
use JSON;
my $file = 'file.json';
my $json_string;
{
local $/; # Locally reset line endings to nothing
open my $fh, '<', $file or die "Can't open file $file!: $!";
$json_string = <$fh>; # Slurp in the entire file
}
my $perl_data_structure = decode_json $json_string;