尋找並刪除具有特定標點符號的重複行

尋找並刪除具有特定標點符號的重複行

我有一個包含數百萬行的文字檔案。有些行包含相同的字母數字序列,但大小寫和標點符號不同。我認為這些行是重複的。我想刪除任何包含句點的重複行,但保留另一行(另一行通常包含下劃線或破折號等標點符號)

輸入:

000
111
12_34
12.34
123-456-789
123.456.789
A.B.C
a_b_c
qwerty
qwertx
abcdefghijklm.nopqrstuvwxy.z
a-B-cdeFghiJklmNopqRStuvwxy__Z
22.2
33.3

期望的輸出:

000
111
12_34
123-456-789
a_b_c
qwerty
qwertx
a-B-cdeFghiJklmNopqRStuvwxy__Z
22.2
33.3

答案1

假設重複值是連續的!


一個可以完成這項工作的 Perl 腳本。

未在大文件上測試!

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

my $file = 'file1'; # path to input file
# read the input file in memory
open my $F, '<', $file or die "unable to open '$file': $!";
my @list = <$F>;chomp @list;
# delete all . - _ from each line and add this new string in the array for comparison
my @res = map {my $tmp=$_; tr/._-//d; [lc$_,$tmp] } @list;
# memoize the first values
my $prev_tst = $res[0][0];  # contains the string without punctuation
my $prev_orig = $res[0][1]; # contains original string
# loop on other values
for my $ind (1 .. @res-1) {
    my ($tst, $orig) = ($res[$ind][0], $res[$ind][1]);
    # te string without punctuation is the same as the previous
    if ($tst eq $prev_tst) {
        # if the previous original value contains dot
        if ($prev_orig =~  tr/.//) {
            # delete it
            undef $res[$ind-1];
        # if the current original value contains dot
        } elsif ($orig =~ tr/.//) {
            # delete it
            undef $res[$ind];
        }
    }
    # memorize value for next step
    $prev_tst = $tst;
    $prev_orig = $orig;
}
# write result to result file
my $result = 'result_file'; # path to result file
open my $R, '>', $result or die "unable to open '$result': $!";

for (@res) {
    next unless defined $_; # skip undifned values
    print $R $_->[1],"\n";
}


答案2

類似的東西

sed 's/\./-/g; s/__*/-/g' /path/to/infile | sort -u > /path/to/outfile

應該能解決問題

相關內容