Удаление символов из столбца, если они появляются менее 20 раз - PullRequest
3 голосов
/ 03 января 2012

У меня есть CSV-файл с двумя столбцами:

cat @ c a t
dog @ d o g
bat @ b a t

Чтобы упростить общение, я использовал английские буквы для этого примера, но я имею дело с CJK в UTF-8.

Я хотел бы удалить любой символ, появляющийся во втором столбце, который появляется в менее чем 20 строках в первом столбце (символы могут быть любыми, от цифр, букв до китайских символов и знаков препинания, но не пробелы).

Например, если «о» появляется в 15 строках в первом столбце, все вхождения «о» удаляются из второго столбца.Если в первом столбце отображается 35 символов «а», изменения не вносятся.

  • Первый столбец изменять нельзя.
  • Мне не нужно считать несколько появленийбуквы в одну строку.Например, у «робота» есть 2 o, но эта деталь не важна, только то, что у «робота» есть «o», так что это считается одной строкой.

Как я могу удалить символыкоторые появляются менее чем в 20 раз?

Ответы [ 3 ]

2 голосов
/ 04 января 2012

Вот скрипт, использующий awk. Измените var num, чтобы он был вашей точкой отсечки частоты. Я установил его на 1, чтобы показать, как он работает с небольшим примером файла. Обратите внимание, что f все еще удаляется, даже если он отображается три раза в одной строке. Кроме того, передача одного и того же входного файла дважды не является опечаткой.

awk -v num=1 '
BEGIN { OFS=FS="@" }
FNR==NR{
    split($1,a,"")
    for (x in a)
        if(a[x] != " " && !c[a[x]]++)
            l[a[x]]++
    delete c
    next
}
!flag++{
    for (x in l)
        if (l[x] <= num)
            cclass = cclass x
}
{
     gsub("["cclass"]", " " , $2)
}1' ./infile.csv ./infile.csv

Пример ввода

$ cat ./infile
fff @ f f f
cat @ c a t
dog @ d o g
bat @ b a t

выход

$ ./delchar.sh
fff @
cat @  a t
dog @
bat @  a t
1 голос
/ 03 января 2012

ответ:

cut -d " " -f #column $file |  sed -e 's/\.//g'  -e 's/\,//g' | tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr

, где $ file - это ваш текстовый файл, а $ column - это столбец, в котором вы должны искать частоту.Он выдаст вам список их частот

, после чего вы сможете продолжить зацикливание на тех результатах, у которых первая цифра больше вашего порога, и всплыть на целые строки.

1 голос
/ 03 января 2012

Решение Perl:

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

open my $IN, '<:utf8', $ARGV[0] or die $!;
my %chars;
while (<$IN>) {
    chomp;
    my @cols = split /@/;
    my %linechars;
    undef @linechars{ split //, $cols[0] };
    $chars{$_}++ for keys %linechars;
}

seek $IN, 0, 0;
my @remove = grep $chars{$_} < 20, keys %chars;
my $remove_reg = '[' . join(q{}, @remove) . ']';

warn $remove_reg;

while (<$IN>) {
    my @cols = split /@/;
    $cols[1] =~ s/$remove_reg//g;
    print join '@', @cols;
}

Я не уверен, как нужно обрабатывать пробелы, поэтому вам может потребоваться настроить скрипт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...