You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Grep多文件匹配并按文件分行输出,无匹配显示NO

解决方案:按文件分组提取data-code值

刚好遇到过类似的需求,我来给你两个靠谱的方案,完美实现你要的按文件分组输出效果!

方法一:用for循环+grep+paste(直观易理解)

这是最容易上手的方案,逐个处理每个文件,把每个文件的匹配值用逗号拼接,无匹配则输出NO:

for file in text*.txt; do
    # 提取当前文件的所有data-code值,并用逗号连接成一行
    codes=$(grep -oP '(?<=data-code=")\d+' "$file" | paste -sd "," -)
    # 如果codes为空就输出NO,否则输出拼接好的字符串
    echo "${codes:-NO}"
done

命令解释:

  • for file in text*.txt:遍历所有符合text*.txt命名规则的文件
  • grep -oP '(?<=data-code=")\d+' "$file":提取当前文件中所有data-code="数字"格式里的数字部分,每个匹配结果单独占一行
  • paste -sd "," -:把当前文件所有换行的匹配值,用逗号连接成一个完整的字符串(-s表示合并同一文件的行,-d ","指定分隔符为逗号)
  • ${codes:-NO}:如果变量codes为空(也就是没有匹配到任何值),就输出NO,否则输出拼接好的data-code字符串

运行这个命令后,输出完全符合你的期望:

1,2
19,48,93
NO
333,444

方法二:用grep+awk(适合批量大文件)

如果要处理的文件数量特别多,用awk一次性处理可以提高效率,利用grep带文件名前缀的输出进行分组:

grep -oP '(?<=data-code=")\d+' text*.txt | awk '
    {
        # 提取冒号后面的匹配值(grep多文件输出格式是"文件名:匹配值")
        value = substr($0, index($0, ":") + 1)
        # 切换到新文件时,输出上一个文件的聚合结果
        if (FILENAME != prev) {
            if (prev != "") {
                print (result ? result : "NO")
            }
            result = value
            prev = FILENAME
        } else {
            # 同一文件的匹配值用逗号拼接
            result = result "," value
        }
    }
    # 处理最后一个文件的输出
    END {
        print (result ? result : "NO")
    }
'

命令解释:

  • grep部分和方法一逻辑一致,但因为处理多个文件,grep会自动给每个匹配项加上文件名:前缀
  • awk通过FILENAME变量识别当前行所属的文件,当检测到切换到新文件时,输出上一个文件的聚合结果,最后在END块处理最后一个文件的输出

这个方法不需要循环遍历文件,直接一次性处理所有grep的输出,适合文件数量极多的场景。

内容的提问来源于stack exchange,提问作者H.Otmane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:16:54