Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Awk Bash计数数字的个数_Awk_Sed_Grep - Fatal编程技术网

Awk Bash计数数字的个数

Awk Bash计数数字的个数,awk,sed,grep,Awk,Sed,Grep,我有几个空格分隔的字符串: 1 -2 3 1 23 456 apple 69 b4n4n45 gr4pe5 -420 lol 10101010101 lol 1 23 a99 99a 9a9 -1 -23 -a99 -99a -9a9 --1 --23 --a99 --99a --9a9 $ awk '{c=0; for (i=1; i<=NF; i++) c+=($i ~ /^-?[0-9]+$/); print c}' file 3 3 3 我想知道每个字符串中的确切数字。

我有几个空格分隔的字符串:

1 -2 3  
1 23 456  
apple 69 b4n4n45 gr4pe5 -420 lol 10101010101 lol
1 23 a99 99a 9a9 -1 -23 -a99 -99a -9a9 --1 --23 --a99 --99a --9a9
$ awk '{c=0; for (i=1; i<=NF; i++) c+=($i ~ /^-?[0-9]+$/); print c}' file
3
3
3
我想知道每个字符串中的确切数字。对于上面的例子,答案应该是[3,3,3,4]。我不想将像
b4n4n45
这样的字符串计算为“数字”。只应计算纯整数字符串

我尝试使用grep和regex:

$ echo $string | grep '[0-9]' | wc
但这对我不起作用。有什么提示吗?

Bash count数字的数量
echo$string | grep-Po'(^ |^-| |-)[0-9]+((?=)|$)'| wc-w
wc-w
将计算给定输入中以空格分隔的子字符串的数量
我们可以使用
grep-Po
(-P表示Perl正则表达式,-o仅输出匹配)来匹配纯数字子字符串

我们可以使用正则表达式定义要保留的子字符串的模式:

  • (^ |^-| |-)
    从四种可能的启动条件之一开始
  • [0-9]+
    仅包含一个或多个整数字符
  • ((?=)|$)
    以空格或行尾字符结尾,
    (?=)
    向前查找空格字符,但不匹配,允许重叠

  • 请您尝试以下内容(使用显示的样本进行测试和编写),这应该也包括负数,因为OP提到了整数,所以我没有考虑计算浮点数。对于所述的3行样本,其输出为
    3

    awk '
    {
      for(i=1;i<=NF;i++){
        if(length(int($i))==length($i)){ count++ }
      }
      print count
      count=""
    }' Input_file
    
    awk'
    {
    对于(i=1;i和grep:

    echo“$string”| grep-Ewo--'-?[0-9]+'| wc-l
    
    • -?[0-9]+
      只是一个正则表达式:可选地是一个连字符,后跟一个或多个数字

    • -w
      是秘方:这是“word regexp”选项。模式隐式地锚定在单词边界标记上。这就是只查找与模式匹配的单词的方法。GNU grep手册页上说:

      测试是匹配的子字符串必须位于 行,或前面有非单词组成字符。类似地,它必须 要么在行尾,要么在后面跟一个非单词成分 性格

      就是这样。
      -w
      选项将其包裹在一个小蝴蝶结中

    • 然后,
      -o
      将匹配的单词吐出,每行一次,
      wc-l
      对它们进行计数

    简单地猛击

    read-ra单词另一个awk:

    $ awk '{for(i=1;i<=NF;i++)if($i+0||$i==0)c++;print c;c=0}' file
    

    编辑:早上喝过咖啡后,我注意到纯整数字符串,所以请注意,这一个也会计算十进制数。

    使用GNU awk for FPAT,并假设您的输入仅为一个数字+减号,如示例所示:

    $ awk -v FPAT='\\<-?[0-9]+\\>' '{print NF}' file
    3
    3
    3
    
    $awk-vfpat='\\''{print NF}文件
    3.
    3.
    3.
    
    对于任何空格分隔的字符串,或使用任何awk:

    1 -2 3  
    1 23 456  
    apple 69 b4n4n45 gr4pe5 -420 lol 10101010101 lol
    1 23 a99 99a 9a9 -1 -23 -a99 -99a -9a9 --1 --23 --a99 --99a --9a9
    
    $ awk '{c=0; for (i=1; i<=NF; i++) c+=($i ~ /^-?[0-9]+$/); print c}' file
    3
    3
    3
    
    $awk'{c=0;for(i=1;i这可能适合您(GNU-sed&bash):

    删除行末尾的所有空白

    将任何0转换为1(我们对数字不感兴趣,只是因为它是一个数字)

    用bash算术表达式替换非空白,该表达式返回数值
    1
    ,否则返回
    0

    +
    替换空白


    计算创建的返回数字计数的算术表达式。

    只有一个正则表达式可以提取纯整数:
    [-+]?[0-9]+
    。将其与
    gsub
    结合使用时,您可以在awk中得到简单的解决方案:

    $ awk '{t=OFS $0 OFS;gsub(FS,OFS OFS,t);print gsub(OFS"[-+]?[0-9]+"OFS,"",t)}'
    
    首先,我们使用
    gsub
    对替换进行计数。
    gsub(ere,repl,str)
    对匹配
    ere
    的所有替换字符串进行替换,并将其替换为字符串
    repl
    。它返回完成的替换总数。这正是我们感兴趣的

    但是仍然存在一个问题。您不能仅用计数替换正则表达式
    [-+]?[0-9]+
    的匹配项,因为这也会对
    foo123bar
    之类的字符串进行计数。为了避免这种情况,我们尝试替换夹在字段分隔符之间的整数

    另一方面,字段分隔符也很棘手。它们本身可以是正则表达式,默认的
    FS=”“
    匹配任何空格。由于输出字段分隔符是固定字符串,最好用
    OFS
    替换
    FS
    。简言之,使用tsv文件时,以下操作将失败:

     awk '{t=FS $0 FS; print gsub(FS"[-+]?[0-9]+"FS,"",t)}' file
    
    虽然这一切都很好,但我们仍然必须注意最后一件事:连续字段。
    gsub
    与重叠不匹配,因此我们必须复制输出字段分隔符

    假设
    OFS=“\u”
    ,那么字符串
    \u123\u456\uquot>将导致计数1,而
    \u123\u456\uquot>将返回2

    $ perl -lane ' $c=0;for(@F) { if(/^-?\d+$/) { $c++; } } print $c ' lenna.txt
    3
    3
    3
    $
    


    -14
    会被算作一个“纯数字”吗?
    2.5
    怎么样?如果可以的话,-14会很好地包含在内。不过不需要小数。整数集应该很好。这是跳出框框思考的,到目前为止,它是唯一一个输出
    3,3
    +的好方法,但它没有处理负表示。(例如,它省略了
    -2
    -420
    )谢谢,我添加了一个“-”来解释负数,但示例的最后一行不会仍然导致
    “69 b-420 10101010101”
    ?(额外的
    'b'
    ?)非常正确,白名单可能是解决这个问题的一个更好的解决方案……这个答案最终匹配了所有场景,有关
    (?=)
    的更多信息,请参阅。
    我想问您是否不必显式设置
    extglob
    ,但事实证明您不必为
    […]设置
    –学到了一些东西!使用posix
    --
    返回一个
    +1
    你介意解释一下这里使用的不同语法技巧吗。我喜欢他们的答案中使用的格式,但你的答案似乎更简洁!字符串
    “155--1111”
    应该得到
    3
    ,但得到的却是
    4
    $ perl -lne ' $c=0; while(/\b-?\d+\b/g) { ++$c }  print $c  ' lenna.txt
    3
    3
    3
    $