我有一长串的零和零:
0
0
0
1
0
0
0
0
0
1
0
0
0
0
0
1
0
0
1
....
Run Code Online (Sandbox Code Playgroud)
我可以很容易地得到1之间的平均零数(只有总数/ 1):
ones=$(grep -c 1 file.txt)
lines=$(wc -l < file.txt)
echo "$lines / $ones" | bc -l
Run Code Online (Sandbox Code Playgroud)
但是如何在两者之间获得零串的长度呢?在上面的简短示例中,它将是:
3
5
5
2
Run Code Online (Sandbox Code Playgroud)
eri*_*son 17
我想包括uniq
一个更容易阅读的方法:
uniq -c file.txt | awk '/ 0$/ {print $1}'
Run Code Online (Sandbox Code Playgroud)
ric*_*ici 10
编辑:固定为最后一行为0的情况
容易在awk:
awk '/1/{print NR-prev-1; prev=NR;}END{if (NR>prev)print NR-prev;}'
Run Code Online (Sandbox Code Playgroud)
在bash中也不是那么困难:
i=0
for x in $(<file.txt); do
if ((x)); then echo $i; i=0; else ((++i)); fi
done
((i)) && echo $i
Run Code Online (Sandbox Code Playgroud)
使用awk
,我会使用一个值为value的字段0
为False 的事实:
awk '!$1{s++; next} {if (s) print s; s=0} END {if (s) print s}' file
Run Code Online (Sandbox Code Playgroud)
返回:
3
5
5
2
Run Code Online (Sandbox Code Playgroud)
另外,请注意该END
块以打印在最后一个之后出现的任何"剩余"零1
.
!$1{s++; next}
如果该字段不为True,即,如果该字段为0
,则递增计数器.然后,跳到下一行.{if (s) print s; s=0}
否则,打印计数器的值并重置它,但只是它包含一些值(0
如果文件以a开头则避免打印1
).END {if (s) print s}
处理完文件后打印计数器的剩余值,但前面没有打印过.如果file.txt 只是一列1和0,则可以使用awk
记录分隔符并将其更改为"1 \n".这使得每个"记录"成为"0 \n"的序列,并且记录中的0的计数是记录的长度除以2.对于前导和尾随的1和0,计数将是正确的.
awk 'BEGIN {RS="1\n"} { print length/2 }' file.txt
Run Code Online (Sandbox Code Playgroud)
这似乎是今天非常受欢迎的问题.加入晚会,这是另一个简短的gnu-awk命令来完成这项工作:
awk -F '\n' -v RS='(1\n)+' 'NF{print NF-1}' file
3
5
5
2
Run Code Online (Sandbox Code Playgroud)
这个怎么运作:
-F '\n' # set input field separator as \n (newline)
-v RS='(1\n)+' # set input record separator as multipled of 1 followed by newline
NF # execute the block if minimum one field is found
print NF-1 # print num of field -1 to get count of 0
Run Code Online (Sandbox Code Playgroud)