我在crontab中运行了一个Perl脚本,该脚本生成了一个包含重复条目的文件,因为在每次运行时,它都会重写先前编写的信息。
我会使用文件sort -u
,但是我会在Perl脚本文件的末尾使用它。
10/10/2017 00:01:39:000;Sagitter
10/11/2017 00:00:01:002;Lupus
10/12/2017 00:03:14:109;Leon
10/12/2017 00:09:00:459;Sagitter
10/13/2017 01:11:03:009;Lupus
12/13/2017 04:29:00:609;Ariet
10/11/2017 00:00:01:002;Lupus
10/12/2017 00:03:14:109;Leon
...
#!/usr/bin/perl
# Libraries
use strict;
use warnings 'all';
%lines = ();
# Remove duplicate
open( TMP_GL_OUTPUT, '>', $OUTPUT_FILE ) or die $!;
while ( <TMP_GL_OUTPUT> ) {
$lines{$_}++;
}
open( OUTFILE, '>', $TMPOUTPUT_FILE ) or die $!;
print OUTFILE keys %lines;
close( OUTFILE );
close( TMP_GL_OUTPUT );
我要去哪里错了?在外壳中感觉比在Perl中短。
sort -u $TMPOUTPUT_FILE > $OUTPUT_FILE
根据ikegamy用户的建议,我已执行以下操作:
move $OUTPUT_FILE, $TMPOUTPUT_FILE; # Copy file
run [ 'sort', '-u', '--', $TMPOUTPUT_FILE ], '>', $OUTPUT_FILE; # Remove duplicate
unlink $TMPOUTPUT_FILE;
答案 0 :(得分:6)
我想你是在问为什么Perl程序比shell脚本长。
首先,您的shell脚本执行的操作与Perl程序完全不同。
Perl等同于
sort -u -- "$TMPOUTPUT_FILE" > "$OUTPUT_FILE"
是
use IPC::Run qw( run );
run [ 'sort', '-u', '--', $TMPOUTPUT_FILE ], '>', $OUTPUT_FILE;
(这两者之间的错误处理有所不同。)
它们的长度没有什么不同。
这带来了第二个区别。 Shell专门执行程序,但是Perl是通用语言。如果在Perl中不再使用它,将是令人惊讶的!
(现在尝试将Perl程序的大小与sort
的来源进行比较...)
答案 1 :(得分:1)
List :: Util是一个核心模块。
use List::Util 'uniq';
print for uniq <>
答案 2 :(得分:0)
您的代码看起来几乎可以。
在您开始之前,我只建议chomp
每行
将元素保存在哈希中。
原因是最后一行,未终止
\n
的情况可能与前一行相同,
但如果没有chomp
,前一行将包含
结束的\n
,最后一个-不。
结果是这两行都是哈希中的不同键。
将我的示例程序(工作状态,如下所示)与您的进行比较,有
除了读取__DATA__
和
写入控制台。
在我的程序中,出于演示目的,我放入了两种打印输出变体, 一个带有键值(重复计数),另一个仅打印键。 在您的程序中仅保留第二个打印输出。
use strict; use warnings; use feature qw(say);
my %lines;
while(<DATA>) {
chomp;
$lines{$_}++;
}
while(my($key, $val) = each %lines) {
printf "%-32s / %d\n", $key, $val;
}
say '========';
foreach my $key (keys %lines) {
say $key;
}
__DATA__
10/10/2017 00:01:39:000;Sagitter
10/11/2017 00:00:01:002;Lupus
10/12/2017 00:03:14:109;Leon
10/12/2017 00:09:00:459;Sagitter
10/13/2017 01:11:03:009;Lupus
12/13/2017 04:29:00:609;Ariet
10/11/2017 00:00:01:002;Lupus
10/12/2017 00:03:14:109;Leon
您的代码未为$OUTPUT_FILE
和$TMPOUTPUT_FILE
分配名称,
您甚至没有声明这些变量,但我认为,在您的实际
代码完成了。
另一个细节是%lines
之前应加上my
,
否则,当您放置use strict;
时,编译器将打印错误。
有比您更快,更短的解决方案。
而不是将行写到哈希表中,直到将它们打印到 第二步,您可以在单个循环中完成该操作:
您甚至可以将其编写为Perl单行代码:
perl -lne"print if !$lines{$_}++" input.txt
如果从Windows cmd
运行上述命令,它将打印输出
到控制台。如果您使用Linux,则可以使用撇号代替双引号。
您当然可以将输出重定向到任何文件,将> output.txt
添加到
上面的命令。
由于-l
选项的限制,为每个输入行执行了代码。
如果您不了解有关Perl单线的任何其他详细信息,请在网上搜索。