Perl 中具有多列的 Linux 文件中的循环命令

Perl 中具有多列的 Linux 文件中的循环命令

我有一个 file.txt 如下,其中有“n”列。我需要在循环中运行命令,需要有第一列值和第二列值。完成后,执行命令以获得第一列值和第三列值,并继续处理一行中的所有列。

例子:

vcloud <ktrcigmv> diskcommand <persistent-disk-1>
vcloud <ktrcigmv> diskcommand <persistent-disk-2>
vlcoud <ktrcsnu1> diskcommand <persistent-disk-1>
vlcoud <ktrcsnu1> diskcommand <persistent-disk-4>
vlcoud <ktrcsnu1> diskcommand <persistent-disk-6>

输入(?):

ktrcigmv       persistent-disk-1 persistent-disk-2
ktrcsnu1       persistent-disk-1 persistent-disk-4 persistent-disk-6
ktrsapahn       vol-71412041887658--dev-sdd-cc04ce65
ktrai2y5h       persistent-disk-1
ktrcibiy       persistent-disk-1
ktrcigf2       persistent-disk-1
ktrcisxh       persistent-disk-1
ktrsapmam       vol-345052022286--dev-sdb-b5d5bdfd vol-345052022286--dev-sdf-9c91de4d
ktrcie8x       persistent-disk-1
ktrcio3s       persistent-disk-1

答案1

使用 的perl模式awk

<file.txt perl -lae '
   system "vcloud", $F[0], "diskcommand", $_ for @F[1..$#F]'

vcloud field-1 diskcommand field-n将为每个运行场2..场最后(请注意,数组索引从 0 开始,而不是 1 中的 1 perl,因此1..$#F每行都有 )。

字段分隔符是任何 ASCII 空白序列(空格、制表符、垂直制表符、换页符、回车符),每行的前导和尾随空白将被忽略。

答案2

也许这是通缉

vcloud ktrcigmv
diskcommand persistent-disk-1
vcloud ktrcigmv
diskcommand persistent-disk-2
vcloud ktrcsnu1
diskcommand persistent-disk-1

或者在“vcloud ...”之后使用 TAB 键底部OP 的一部分作为输入:

vcloud ktrcigmv diskcommand persistent-disk-1
vcloud ktrcigmv diskcommand persistent-disk-2
vcloud ktrcsnu1 diskcommand persistent-disk-1
vcloud ktrcsnu1 diskcommand persistent-disk-4
vcloud ktrcsnu1 diskcommand persistent-disk-6
vcloud ktrsapahn        diskcommand vol-71412041887658--dev-sdd-cc04ce65
vcloud ktrai2y5h        diskcommand persistent-disk-1
vcloud ktrcibiy diskcommand persistent-disk-1
vcloud ktrcigf2 diskcommand persistent-disk-1
vcloud ktrcisxh diskcommand persistent-disk-1
vcloud ktrsapmam        diskcommand vol-345052022286--dev-sdb-b5d5bdfd
vcloud ktrsapmam        diskcommand vol-345052022286--dev-sdf-9c91de4d
vcloud ktrcie8x diskcommand persistent-disk-1
vcloud ktrcio3s diskcommand persistent-disk-1

这看起来像顶部OP 的一部分,减去“<”。

这是通过例如:

while (<>) {
    ($v, @ds) = split;
    for $d (@ds) { 
        print "vcloud $v\t";
        print "diskcommand $d\n";
    }
}

然后将“打印”替换为“系统”。

($v, @ds)需要周围的括号- 这是第一项和其余项分开的地方。


我最初的解释(相反。输入=输出):

while (<>) {
    @F = split;
    $tbl{$F[1]} .= $F[3];
}
for $k (keys %tbl) {
    print "$k $tbl{$k}", "\n";
}

这打印:

]# perl kt.pl ktxt 
<ktrcigmv> <persistent-disk-1><persistent-disk-2>
<ktrcsnu1> <persistent-disk-1><persistent-disk-4><persistent-disk-6>

我很乐意解释一下。

使用“自动分割”perl -a ...选项,您可以将其压缩为:

$tbl{$F[1]} .= "$F[3] ";
END {
for $k (keys %tbl) { print "$k:   $tbl{$k}", "\n" }
}

现在打印,添加了一些格式:

]# perl -a kt.pl ktxt 
<ktrcsnu1>:   <persistent-disk-1> <persistent-disk-4> <persistent-disk-6> 
<ktrcigmv>:   <persistent-disk-1> <persistent-disk-2>

使用perl -aorperl -F数组@F是“神奇的”,这就是我在第一个示例中也使用它的原因。它代表“领域”。$F[0]是第一个字段。

相关内容