[英]Extracting unique values from multiple files in Perl
我有幾個制表符分隔的數據文件。 我需要提取這些數據文件的某一列(例如第25列)中的所有唯一值,並將這些值寫入輸出文件中以進行進一步處理。 我如何在Perl中做到這一點? 記住,我需要考慮同一文件夾中的多個文件。
編輯:到目前為止,我完成的代碼是這樣的。
#!/usr/bin/perl
use warnings;
use strict;
my @hhfilelist = glob "*.hh3";
for my $f (@hhfilelist) {
open F, $f || die "Cannot open $f: $!";
while (<F>) {
chomp;
my @line = split /\t/;
print "field is $line[24]\n";
}
close (F);
}
問題是當我讀取每個文件的每一行時,如何有效地創建唯一值的哈希/數組。 或者,如果我填充整個數組然后刪除重復項,它會更快嗎?
對於Perl解決方案,請使用Text::CSV
模塊來解析平面(X分隔)文件-構造函數接受指定分隔符的參數。 對循環中的每個文件執行此操作,並使用glob()
生成給定目錄中的File::Find
或File::Find
子目錄的文件列表
然后,為了獲得唯一值,對於每一行,將第25列存儲在哈希中。
例如,檢索值后:
$colref = $csv->getline($io);
$unique_values_hash{ $colref->[24] } = 1;
然后,遍歷哈希鍵並打印到文件。
對於非Perl Shell解決方案,您可以簡單地執行以下操作:
cat MyFile_pattern | awk -F'\t' 'print $25' |sort -u > MyUniqueValuesFile
您可以用cut
替換awk
請注意,非Perl解決方案僅在文件本身中的字段中不包含TAB且未引用各列的情況下才有效。
有關如何處理該問題的一些技巧:
glob
: glob '.* *'
File::Find
的find
函數 \\t
字符的Text::CSV
作為分隔符,提取所需的值並寫入文件 perl -F/\\t/ -ane 'print"$F[24]\n" unless $seen{$F[24]}++' inputs > output
perl -F/\\t/ -ane 'print"$F[24]\n" unless $seen{$F[24]}++' *.hh3 > output
命令行開關-F/\\\\t/ -an
表示遍歷每個輸入文件中的每一行,並將制表符上的行拆分為數組@F
。
$F[24]
引用每行第25個字段中的值(在第24個和第25個制表符之間)
$seen{...}
是一個哈希表,用於跟蹤已觀察到的值。 第一次觀察到值時, $seen{VALUE}
為0,因此Perl將執行語句print"$F[24]\\n"
。 每隔兩次觀察該值, $seen{VALUE}
將為非零,並且該語句將不會執行。 這樣,每個唯一值將被精確地打印一次。
在與較大腳本相似的上下文中:
my @hhfilelist = glob "*.hh3";
my %values_in_field_25 = ();
for my $f (@hhfilelist) {
open F, $f || die "Cannot open $f: $!";
while (<F>) {
my @F = split /\t/;
$values_in_field_25{$F[24]} = 1;
}
close (F);
}
my @unique_values_in_field_25 = keys %values_in_field_25; # or sort keys ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.