處理純文字數據

處理純文字數據

我有這個純文字文件,需要自動檢查它並將結果寫入另一個純文字檔案中。請注意,我將交替使用純文字和 CSV,因為 CSV 是純文本,資料之間有通用分隔符號(逗號、製表符等)。

數據舉例

ABD-01A
ABD-01B
ABD-01C
AL-25A
AL-25B

流程一- 識別資料的前兩部分 ( text- number) 以重複並在輸出 CSV 中對它們進行計數:

ABD-01,1
ABD-01,2
ABD-01,3
AL-25,1
AL-25,2

流程二- 上面收集的資料的第一部分有一個在不同文件上分配給它們的主鍵。我還想獲取新生成的文件中提到的主鍵:

#primary key file
1,ABD-01
2,ABD-02
3,AL-02
20,AL-25

#newly generated file
1,ABD-01,1
1,ABD-01,2
1,ABD-01,3
20,AL-25,1
20,AL-25,2

基本上,我問她是否有任何軟體可以幫助我在 Windows 或基於 Linux 的作業系統上完成此操作。 Bash 可以幫助我進行更簡單的處理,但我認為它不能處理這麼多。請指教。

答案1

  1. 選擇您喜歡的語言 – Perl 可以很好地處理文字; Python、PHP 和 Ruby 都可以,只是慢一點。
  2. 首先讀取密鑰檔:
    • 將每一key,data行分成keydata
    • 然後將兩者儲存在字典/哈希/數組中:keys[data] = key
    • 另外counts[data] = 0,如果語言需要初始化
  3. 讀取所有資料檔:
    1. 使用正規表示式找出每行開頭的“TEXT-NUMBER”數據,
    2. counts[data]一,
    3. 並立即輸出keys[data]、行和counts[data]

我用 Perl 和 Python 編寫了一個範例腳本,所以您可以選擇:

進程.pl

#!/usr/bin/env perl
use strict;

sub usage {
    print "Usage: $0 <key_file> <data_file...>\n";
    return 2;
}

my $keys_file = shift(@ARGV) // exit(usage);
my @data_files = @ARGV;

my %keys;   # $data => $primarykey
my %counts; # $data => $count

# Read keys

open(my $fh, "<", $keys_file) or die "$!";
while (my $line = <$fh>) {
    chomp($line);
    my ($key, $datum) = split(/,/, $line, 2);
    if (!defined $datum) {
        warn "$keys_file: line $. not in KEY,DATA format: '$line'\n";
        next;
    }

    $keys{$datum} = $key;
    $counts{$datum} = 0;
}
close($fh);

# Read and output data

my $ex = qr/^(\w+-\d+)\w*/;
for my $data_file (@data_files) {
    open(my $fh, "<", $data_file) or die "$!";
    while (my $line = <$fh>) {
        chomp($line);
        if ($line =~ /$ex/) {
            my $datum = $1;
            if (!defined $keys{$datum}) {
                warn "no primary key found for data '$datum'\n";
                next;
            }

            # Increment count, then print processed line immediately
            $counts{$datum}++;
            print "$keys{$datum},$&,$counts{$datum}\n";
        }
        else {
            warn "$data_file: line $. does not begin with TEXT-NUMBER: '$_'\n";
        }
    }
    close($fh);
}

進程.py

#!/usr/bin/env python
from __future__ import print_function
import sys
import re

def usage():
    print("Usage: %s <key_file> <data_file...>" % sys.argv[0])
    return 2

try:
    keys_file = sys.argv[1]
    data_files = sys.argv[2:]
except IndexError:
    sys.exit(usage())
except ValueError:
    sys.exit(usage())

keys = {}
counts = {}

# Read keys

for line in open(keys_file, "r"):
    try:
        key, datum = line.strip().split(",", 1)
    except ValueError:
        print("%s: line not in KEY,DATA format: %r" \
            % (keys_file, line.strip()), file=sys.stderr)
        continue

    keys[datum] = key
    counts[datum] = 0

# Read and output data

ex = re.compile(r'^(\w+-\d+)\w*')
for data_file in data_files:
    for line in open(data_file, "r"):
        line = line.strip()
        m = re.match(ex, line)
        if m:
            datum = m.group(1)
            if datum not in keys:
                print("no primary key found for data %r" % datum,
                    file=sys.stderr)
                continue

            # Increment count, then print processed line immediately
            counts[datum] += 1
            print("%s,%s,%d" % (keys[datum], m.group(0), counts[datum]))
        else:
            print("%s: line does not begin with TEXT-NUMBER: %r" \
                % (data_file, line.strip()), file=sys.stderr)

答案2

我會在Python使用常用表達。只需輸入python您的 shell 即可查看它是否已安裝。

否則你可以使用珀爾。只需輸入perl您的 shell 即可查看它是否已安裝。是有正規表示式的內建支持

答案3

流程1

perl count.pl datafile …

其中 count.pl 類似

#!perl
use strict;
use warnings;

my %headwordcount;

while (<>) {
  if (/^([A-Z]+-\d+)/) { $headwordcount{$1}++; }
  # else { warn "Bad data: $_"; } # uncomment line for data warnings
}

END {
  foreach (sort keys %headwordcount) {
     print "$_,$headwordcount{$_}\n";
  }
}

未經測試,買者自負。

流程2

添加類似的東西

   my %key;

   BEGIN {
     my $keyfilename = 'primary.key';
     open my $fh, '<', $keyfilename or die "Can't read '$keyfilename' - $!\n";
     while (<$fh>) {
        chomp;
        my ($key,$headword) = split(/,/, $_, 2);
        $key{$headword} = $key;        
     }
     close $fh;
   }

並將列印行更改END {}

   print "$key{$_},$_,$headwordcount{$_}\n";

再次,未經測試。

如果資料檔案包含金鑰檔案中沒有的詞條,您將產生警告。您可以檢查是否$key{$_}未定義,如果是則列印 w/o key。

相關內容