字数统计并输出
Word count and it output
我有以下几行:
123;123;#rss
123;123;#site #design #rss
123;123;#rss
123;123;#rss
123;123;#site #design
并且需要计算每个标签出现的次数,执行以下操作:
grep -Eo '#[a-z].*' ./1.txt | tr "\ " "\n" | uniq -c
即首先select只有字符串中的标签,然后将它们分解并计数。
输出:
1 #rss
1 #site
1 #design
3 #rss
1 #site
1 #design
而不是预期的:
2 #site
4 #rss
2 #design
看来问题出在非打印字符上,导致计数不正确。或者是别的什么?谁能提出正确的解决方案?
uniq -c
仅适用于已排序的输入。
此外,您可以通过将正则表达式更改为 #[a-z]*
.
来删除 tr
grep -Eo '#[a-z]*' ./1.txt | sort | uniq -c
打印
2 #design
4 #rss
2 #site
符合预期。
使用 awk 作为替代:
awk -F [" "\;] '{ for(i=3;i<=NF;i++) { map[$i]++ } } END { for (i in map) { print map[i]" "i} }' file
将字段分隔符设置为 space 或“;”然后从第三个字段循环到最后一个字段(NF),添加到数组映射中,以字段为索引,递增计数器为值。在文件处理结束时,遍历地图数组并打印 indexes/values.
可以一次性完成gnu awk
:
awk -v RS='#[a-zA-Z]+' 'RT {++freq[RT]} END {for (i in freq) print freq[i], i}' file
2 #site
2 #design
4 #rss
否则 grep + awk
解决方案:
grep -iEo '#[a-z]+' file |
awk '{++freq[]} END {for (i in freq) print freq[i], i}'
2 #site
2 #design
4 #rss
只有你展示的样本,请你试试看。在 GNU awk
.
中编写和测试
awk '
{
while([=10=]){
match([=10=],/#[^ ]*/)
count[substr([=10=],RSTART,RLENGTH)]++
[=10=]=substr([=10=],RSTART+RLENGTH)
}
}
END{
for(key in count){
print count[key],key
}
}' Input_file
输出如下。
2 #site
2 #design
4 #rss
解释:为以上添加详细解释。
awk ' ##Starting awk program from here.
{
while([=12=]){ ##Running while till line value.
match([=12=],/#[^ ]*/) ##using match function to match regex #[^ ]* in current line.
count[substr([=12=],RSTART,RLENGTH)]++ ##Creating count array which has index as matched sub string and keep increasing its value with 1 here.
[=12=]=substr([=12=],RSTART+RLENGTH) ##Putting rest of line after match into currnet line here.
}
}
END{ ##Starting END block of this program from here.
for(key in count){ ##using for loop to go throgh count here.
print count[key],key ##printing value of count which has index as key and key here.
}
}
' Input_file ##Mentioning Input_file name here.
$ cut -d';' -f3 file | tr ' ' '\n' | sort | uniq -c
2 #design
4 #rss
2 #site
我有以下几行:
123;123;#rss
123;123;#site #design #rss
123;123;#rss
123;123;#rss
123;123;#site #design
并且需要计算每个标签出现的次数,执行以下操作:
grep -Eo '#[a-z].*' ./1.txt | tr "\ " "\n" | uniq -c
即首先select只有字符串中的标签,然后将它们分解并计数。
输出:
1 #rss
1 #site
1 #design
3 #rss
1 #site
1 #design
而不是预期的:
2 #site
4 #rss
2 #design
看来问题出在非打印字符上,导致计数不正确。或者是别的什么?谁能提出正确的解决方案?
uniq -c
仅适用于已排序的输入。
此外,您可以通过将正则表达式更改为 #[a-z]*
.
tr
grep -Eo '#[a-z]*' ./1.txt | sort | uniq -c
打印
2 #design
4 #rss
2 #site
符合预期。
使用 awk 作为替代:
awk -F [" "\;] '{ for(i=3;i<=NF;i++) { map[$i]++ } } END { for (i in map) { print map[i]" "i} }' file
将字段分隔符设置为 space 或“;”然后从第三个字段循环到最后一个字段(NF),添加到数组映射中,以字段为索引,递增计数器为值。在文件处理结束时,遍历地图数组并打印 indexes/values.
可以一次性完成gnu awk
:
awk -v RS='#[a-zA-Z]+' 'RT {++freq[RT]} END {for (i in freq) print freq[i], i}' file
2 #site
2 #design
4 #rss
否则 grep + awk
解决方案:
grep -iEo '#[a-z]+' file |
awk '{++freq[]} END {for (i in freq) print freq[i], i}'
2 #site
2 #design
4 #rss
只有你展示的样本,请你试试看。在 GNU awk
.
awk '
{
while([=10=]){
match([=10=],/#[^ ]*/)
count[substr([=10=],RSTART,RLENGTH)]++
[=10=]=substr([=10=],RSTART+RLENGTH)
}
}
END{
for(key in count){
print count[key],key
}
}' Input_file
输出如下。
2 #site
2 #design
4 #rss
解释:为以上添加详细解释。
awk ' ##Starting awk program from here.
{
while([=12=]){ ##Running while till line value.
match([=12=],/#[^ ]*/) ##using match function to match regex #[^ ]* in current line.
count[substr([=12=],RSTART,RLENGTH)]++ ##Creating count array which has index as matched sub string and keep increasing its value with 1 here.
[=12=]=substr([=12=],RSTART+RLENGTH) ##Putting rest of line after match into currnet line here.
}
}
END{ ##Starting END block of this program from here.
for(key in count){ ##using for loop to go throgh count here.
print count[key],key ##printing value of count which has index as key and key here.
}
}
' Input_file ##Mentioning Input_file name here.
$ cut -d';' -f3 file | tr ' ' '\n' | sort | uniq -c
2 #design
4 #rss
2 #site