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

如何将Shell变量传递给grep的-A参数提取SDF文件原子坐标

解决grep -A参数传递Shell变量的问题

核心解决方案

你之前的命令出错主要有两个原因:一是缺少要匹配的目标模式(V2000),导致grep等待标准输入;二是部分写法对参数格式处理错误。正确的命令应该是:

grep -A "$no_atoms" "V2000" *.sdf

或者当变量值为纯数字时,无引号的写法也安全:

grep -A $no_atoms V2000 *.sdf

这样就能匹配到包含V2000的行,并输出该行之后的$no_atoms行(即所有原子坐标)。

为什么之前的写法失败?

  • grep -A{$no_atoms} *.sdf:-A参数不需要额外的花括号,grep会把{42}当成一个非法的长度参数。
  • grep -A\$no_atoms *.sdf:转义$导致变量未被解析,grep直接把$no_atoms当成无效的长度值。
  • grep -A"$no_atoms" *.sdf:未指定匹配模式,grep进入等待标准输入的状态,因此会出现光标卡住的情况。

优化:处理多个SDF文件的场景

如果目录下有多个SDF文件(每个文件原子数不同),直接用grep V2000 *.sdf | awk '{print $1}'会把所有文件的原子数合并到一个变量中,传递给grep -A会出错。可以用循环逐个处理:

for file in *.sdf; do
    no_atoms=$(grep "V2000" "$file" | awk '{print $1}')
    grep -A "$no_atoms" "V2000" "$file"
done

每个文件会单独提取对应的原子数,并输出正确的坐标行。

额外技巧:用awk一步完成提取

不需要grep+变量传递,直接用awk就能高效完成原子数读取和坐标提取:

awk '/V2000/{n=$1; print; for(i=0;i<n;i++){getline; print}}' *.sdf

这个命令的逻辑:

  1. 匹配到含V2000的行时,记录第一个字段(原子数n)
  2. 打印该行,然后循环读取并打印接下来的n行(原子坐标)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 15:54:56