使用grep和sed统计单行长文件多模式出现次数及参数处理问题
实现方案
核心问题解决
1. 遍历除首个参数外的所有模式参数
Bash 中可以直接用${@:2}获取从第二个位置开始的所有入参,直接用于循环遍历即可,无需手动指定参数序号。如果需要兼容 POSIX shell,也可以先把第一个参数存为文件名后执行shift,剩下的所有参数就是待匹配的模式。
2. 统计无换行文本中的模式出现次数
不需要自己实现替换换行逻辑,grep 自带的-o参数会仅输出匹配到的内容,且每个匹配结果单独占一行,直接通过wc -l统计行数即可得到出现次数,完美适配无换行的长文本场景。
完整可运行脚本
#!/bin/bash # 参数校验 if [ $# -lt 2 ]; then echo "用法: $0 <目标文件> <待匹配模式1> [待匹配模式2...]" exit 1 fi target_file="$1" # 遍历所有待匹配模式 for pattern in "${@:2}"; do # 统计次数:grep -o 输出每个匹配,wc -l 计数 count=$(grep -o "$pattern" "$target_file" | wc -l) echo "$pattern $count" done
原代码问题说明
你之前的写法存在几个典型错误:
- 单引号包裹的 sed 表达式不会解析变量,
's/$PATTERN/FIND/g'里的$PATTERN不会被替换为实际的模式值,需要用双引号包裹表达式 - 管道后的 grep 不需要再加
$file参数,否则会直接读取原文件忽略管道输入 - 循环内加了
exit语句,第一次循环结束就会直接退出脚本,无法遍历所有模式 wc-1是拼写错误,正确写法是wc -l
可选sed实现方案(匹配你最初的思路)
如果你一定要用sed实现匹配后换行的逻辑,可以用如下写法,效果和grep方案一致:
count=$(sed "s/$pattern/&\n/g" "$target_file" | grep -c "$pattern")
这里的&代表sed匹配到的内容,替换为匹配内容+换行符,每个匹配会被拆到单独行,再用grep -c直接统计匹配行数即可。
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

