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
$