Regex 使用bash文本实用程序计算字符串匹配后的出现次数
我正试图用一些很酷的conky配置重新组织我的桌面。因为我非常喜欢Emacs中的组织模式,所以我想从我保存日常任务的组织文件中导出任务,并将其显示在conky中。假设我有这样一个文件:Regex 使用bash文本实用程序计算字符串匹配后的出现次数,regex,bash,sed,awk,grep,Regex,Bash,Sed,Awk,Grep,我正试图用一些很酷的conky配置重新组织我的桌面。因为我非常喜欢Emacs中的组织模式,所以我想从我保存日常任务的组织文件中导出任务,并将其显示在conky中。假设我有这样一个文件: * first item ** subitem ** subitem ** subitem * second item ** subitem ** subitem * third item ** subitem ** subitem ** subitem ** subitem 我想创建一个任务摘要,它将检查以*
* first item
** subitem
** subitem
** subitem
* second item
** subitem
** subitem
* third item
** subitem
** subitem
** subitem
** subitem
我想创建一个任务摘要,它将检查以*
开头的所有任务,并统计前面的***
项。那么我想用合适的方式来表达:
* first item [3]
* second item [2]
* third item [4]
虽然我可以在grep
中找到仅以一个*
开头的字符串:
grep "^\\* " foo.org
我可以用以下方法计算**
的出现次数:
grep -c "^\\*\{2\}" foo.org
我怎样才能达到预期的结果?当然,可以使用Python或Ruby,但我只想使用bash实用程序。关于您提供的示例文件:
awk '!/^*/{next}$1=="*"{sub("\\*+ ","");p=$0}$1="**"{c[p]+=1}END{for(i in c) printf "* %s [%s]\n", i ,c[i]-1}'
返回所需的输出
* second item [2]
* first item [3]
* third item [4]
如果需要排序,请在sort
awk command | sort -k2,2
这不是我的第一选择,但您可以在纯bash(无叉子)中实现这一点: 需要指出的事情:
是允许正则表达式匹配的bash扩展[[…=~…]]
用于测试变量是否存在declare-p
- 如果输入不符合描述,脚本将执行有趣的操作,例如空行、没有*或**前缀的行
*
开头的,它仍然在“计数”它。使用grep管道到awk是多余的。我相应地更改了awk过滤器。你应该删除我的“调整”。真漂亮!塔克斯!但我注意到了一个奇怪的行为:awk
为什么自己排序行?!我可以使用“排序”。。。没关系!=)@ripat,我喜欢关联数组,但我相信您可以使用awk以保留输入顺序的方式实现这一点:)
#!/bin/bash
set -u
unset HEADING LINE COUNT
COUNT=0
while read LINE; do
if [[ "$LINE" =~ '^\* ' ]]; then
#print previous, if it exists
declare -p HEADING > /dev/null 2>&1 && echo "$HEADING [${COUNT}]"
HEADING=$LINE
COUNT=0
elif [[ "$LINE" =~ '^\*\* ' ]]; then
let COUNT++
else
echo "Unexpected input" 1>&2
fi
done
echo "$HEADING [${COUNT}]"