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

如何在Bash中从指定格式字符串提取名称并处理空行?

问题:提取包含空格的名称(排除后续数字/数字对)

输入数据格式为 <name> <a>/<b>,同一行可能出现0次或多次,且/两侧可能存在多余空格。需要提取出的目标名称示例如下:

name1
name2
name3 last3

现有错误代码:

echo "name1 11/22 name2 33 / 44 name3 last3 55/66" \
 | grep -o -E '\b[a-zA-Z][a-zA-Z0-9. ]+\b'

错误输出(错误地把数字也包含进名称):

name1 11
name2 33
name3 last3 55

要求:脚本处理空行时无输出,以下是几种可行的Bash实现方法:

方法1:使用sed(简洁高效)

echo "name1 11/22 name2 33 / 44 name3 last3 55/66" | sed -E 's/([a-zA-Z][a-zA-Z0-9. ]*)[[:space:]]+[0-9]+[[:space:]]*\/[[:space:]]*[0-9]+/\1\n/g; s/[[:space:]]*$//'

说明:

  • 正则匹配完整的<name> <a>/<b>单元,将名称部分保留,替换为名称\n
  • 最后一步去掉末尾多余空格,空行因无匹配项直接输出为空

方法2:使用awk(逻辑清晰,易扩展)

echo "name1 11/22 name2 33 / 44 name3 last3 55/66" | awk '{
    name = ""
    next_is_slash = 0
    for (i=1; i<=NF; i++) {
        if ($i ~ /^[0-9]+[[:space:]]*\/[[:space:]]*[0-9]+$/) {
            print name
            name = ""
        } else if ($i ~ /^[0-9]+$/) {
            if (next_is_slash) {
                next_is_slash = 0
                print name
                name = ""
            } else {
                next_is_slash = 1
            }
        } else if ($i == "/") {
            next_is_slash = 0
            print name
            name = ""
        } else {
            name = (name ? name " " : "") $i
        }
    }
}'

说明:

  • 逐字段遍历输入,区分名称、数字、/三种类型的字段
  • 遇到完整的<a>/<b>或拆分的<a> / <b>时,输出之前累加的名称并重置状态
  • 空行时字段数为0,循环不执行,无输出

方法3:使用支持PCRE的grep(简洁的正则匹配)

echo "name1 11/22 name2 33 / 44 name3 last3 55/66" | grep -o -P '[a-zA-Z][a-zA-Z0-9. ]*(?=\s+(?:\d+\s*\/\s*\d+|\d+\s+\/\s+\d+))'

说明:

  • 利用正向预查((?=...))匹配后面紧跟<a>/<b>或<a> / <b>的名称部分
  • 仅提取符合条件的名称,不会包含后续数字;空行无匹配项,输出为空

内容的提问来源于stack exchange,提问作者Daniel YC Lin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:43:10