【问题标题】:Deleting characters from a column if they appear fewer than 20 times如果字符出现少于 20 次,则从列中删除字符
【发布时间】:2012-02-01 13:48:30
【问题描述】:

我有一个包含两列的 CSV 文件:

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

为了简化交流,我在这个例子中使用了英文字母,但我处理的是 UTF-8 中的 CJK。

我想删除第二列中出现的任何字符,该字符出现在第一列中少于 20 行(字符可以是数字、字母、汉字和标点符号,但不能是空格)。

例如,如果“o”出现在第一列的 15 行中,则从第二列中删除所有出现的“o”。如果“a”出现在第一列的 35 行中,则不做任何更改。

  • 不得更改第一列。
  • 我不需要计算一个字母在一行中出现的次数。例如“robot”有2个o,但这个细节并不重要,只是“robot”有一个“o”,所以算作一行。

如何删除出现次数少于 20 次的字符?

【问题讨论】:

    标签: bash shell csv sed awk


    【解决方案1】:

    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;
    }
    

    我不确定应该如何处理空白,因此您可能需要调整脚本。

    【讨论】:

      【解决方案2】:

      答案是:

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

      其中 $file 是您的文本文件,$column 是您需要查找其频率的列。它为您提供了他们的频率列表

      然后你可以继续循环那些第一个数字大于你的阈值的结果并在整行上搜索。

      【讨论】:

        【解决方案3】:

        这是一个使用awk 的脚本。将 var num 更改为您的频率截止点。我已将其设置为1,以展示它如何处理一个小样本文件。请注意f 是如何被删除的,即使它在一行中出现了 3 次。此外,两次传递相同的输入文件也不是错字。

        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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-20
          • 2023-02-20
          • 2020-06-16
          • 2014-06-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多