如何计算一行中除特定字符之外的字符数?


9

这是零件文件

N W N N N N N N N N N
N C N N N N N N N N N
N A N N N N N N N N N
N N N N N N N N N N N
N G N N N N N N N N N
N C N N N C N N N N N
N C C N N N N N N N N

在每一行中,我要计算所有非“ N”字符的总数

我的愿望输出

1
1
1
0
1
2
2

使用sed更换的东西,你不关心,并awk计算剩余长度sed 's/N//g ; s/\s//g' file | awk '{ print length($0); }'
罗尔夫

Answers:


13

GNU awk解决方案:

awk -v FPAT='[^N[:space:]]' '{ print NF }' file
  • FPAT='[^N[:space:]]'-定义字段值的模式(Nchar和空格除外的任何字符)

预期输出:

1
1
1
0
1
2
2


7

假设除空格字符和 N

$ perl -lne 'print tr/N //c' ip.txt 
1
1
1
0
1
2
2
  • 的返回值tr是替换了多少个字符
  • c 补充给定的字符集
  • 注意-l选项的使用,从输入行中删除换行符,以免出现一个错误,并且还为print语句添加换行符


更通用的解决方案

perl -lane 'print scalar grep {$_ ne "N"} @F' ip.txt 
  • -a自动在空格上分割输入行的选项,保存在@F数组中
  • grep {$_ ne "N"} @F返回@F与字符串不匹配的所有元素的数组N
    • 正则表达式将是 grep {!/^N$/} @F
  • 使用scalar将给出数组元素的数量

6

替代awk解决方案:

awk '{ print gsub(/[^N[:space:]]/,"") }' file
  • gsub(...)-该gsub()函数返回替换的数量。

输出:

1
1
1
0
1
2
2

6

另一种awk方法(对于空行将返回-1)。

awk -F'[^N ]' '$0=NF-1""' infile

或者在复杂的情况下,它将仅在空白行上返回-1,在空白行(制表符/空格)上返回0

awk -F'[^N \t]+' '$0=NF-1""' infile

将打印-1空行...但是然后可能需要区分仅由N /空格和空行组成的行...
Sundeep

1
@Sundeep是的,这是正确的。还看到我的更新,其中线是只包含制表符或空格,表示为0
αғsнιη

5
  1. trPOSIX shell脚本:

    tr -d 'N ' < file | while read x ; do echo ${#x} ; done
    
  2. bashksh以及zsh

    while read x ; do x="${x//[ N]}" ; echo ${#x} ; done < file
    

1
可以awk '{print length()}'用来避免较慢的shell循环..但后来人们可以用awk本身来完成所有工作……
Sundeep

@Sundeep,的确是这样(如果两者同时启动),那么awk循环比shell循环快。但是,shell始终位于内存中,awk可能不是-当awk尚未加载或换出外壳时,加载它的开销(时间损失)可能大于运行的好处awk-尤其是在小型机上环。在这种情况下,(本例中),awk可以是较慢的
agc

好吧,我当然不担心小东西的时间...参见unix.stackexchange.com/questions/169716/…–
Sundeep

1
@Sundeep,我担心。前段时间,我曾经使用过基于软盘的Linux发行版,它可以在几兆ram的内存中运行于软盘上。无需awk在shell脚本中使用,可使这样的系统全面爬行。通常:相同的延迟拖延适用于固件有限的系统或负载较重的任何系统。
agc

1

的简短组合trawk

$ tr -d ' N' <file.in | awk '{ print length }'
1
1
1
0
1
2
2

这将从输入文件中删除所有Ns的空格,awk仅打印每行的长度。


0

另一种简单的方法是在大多数Unix环境中预先安装的python中进行操作。将以下代码放入.py文件中:

with open('geno') as f:
    for line in f:
        count = 0
        for word in line.split():
            if word != 'N':
                count += 1
        print(count)

然后执行:

python file.py

从您的终端。以上是:

  • 对于名为“ geno”的文件中的每一行
  • 将计数器设置为0,并在每次找到值时将其递增!='N'
  • 当到达当前行的末尾时,打印计数器并转到下一行
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.