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

如何在Bash中定义函数,用Awk提取两正则间的代码块?

解决Awk与Bash函数参数冲突的代码块提取问题

问题背景

要从文件中提取匹配**起始正则pat1到结束正则pat2**的代码块,原本直接用Awk命令可以正常工作:

$ awk '/dw_pcie_ops.*=/{inblk=1} inblk==1&&/^}/{print $0; inblk=0} inblk==1{print $0}' drivers/pci/controller/dwc/pci-meson.c
static const struct dw_pcie_ops dw_pcie_ops = {
    .link_up = meson_pcie_link_up,
    .start_link = meson_pcie_start_link,
};

为了复用功能,将其封装为Bash函数patinpat,但调用patinpat dw_pcie_ops.*= ^} drivers/pci/controller/dwc/pci-meson.c时,虽参数传递正常,却无法提取目标代码块。函数原定义如下:

# usage : patinpat pat1 pat2 filename
function patinpat ( ) {
echo 'running patinpat'
echo '$1 = ' $1
echo '$2 = ' $2
echo '$3 = ' $3
awk '/"$1"/{inblk=1} inblk==1&&/"$2"/{print $0; inblk=0} inblk==1{print $0}' "$3"
}

错误原因

  1. Awk代码被双引号包裹时,内部的$1、$2是Awk的内置变量(代表当前行的第1、2个字段),而非Bash函数的参数
  2. 正则表达式被额外的双引号包裹(/"$1"/),导致传入的正则被当作包含引号的字符串匹配,而非原始正则规则

解决方法

使用Awk的-v选项将Bash函数的参数传递给Awk变量,避免变量冲突,同时去掉正则的多余引号:

# usage : patinpat pat1 pat2 filename
function patinpat() {
    echo 'running patinpat'
    echo '$1 = ' "$1"
    echo '$2 = ' "$2"
    echo '$3 = ' "$3"
    awk -v start="$1" -v end="$2" '
        $0 ~ start { inblk = 1 }
        inblk == 1 {
            print $0
            if ($0 ~ end) inblk = 0
        }
    ' "$3"
}

测试验证

调用函数:

$ patinpat dw_pcie_ops.*= ^} drivers/pci/controller/dwc/pci-meson.c

输出结果:

running patinpat
$1 =  dw_pcie_ops.*=
$2 =  ^}
$3 =  drivers/pci/controller/dwc/pci-meson.c
static const struct dw_pcie_ops dw_pcie_ops = {
    .link_up = meson_pcie_link_up,
    .start_link = meson_pcie_start_link,
};

内容的提问来源于stack exchange,提问作者Chan Kim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:30:27