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

如何仅用sed、awk等shell命令按行块内machine值修改对应request字段

问题描述

现有一个包含多段行块的文件,示例内容如下:

line1
line1
-----
machine:chrome
purpose:
language:v2
request:v3
additional: v4
os:v4
-----
machine:firefox
purpose:
language:v2
request:v6
os:v4
-----
machine:helper
purpose:
language:v2
request:v8
os:v4
-----
another line

这些行块包含的元素不一定完全相同,但都统一以machine字段开头、os字段结尾。需求是仅使用shell命令实现:逐段解析每个从machine到os的行块内machine开头行的取值,用该取值执行对应shell命令,再将命令输出填入同块的request字段中,是否可以仅使用sed和awk实现该需求?

预期输出效果

line1
line1
-----
machine:chrome
purpose:
language:v2
request:[output of result of ps -ef chrome | awk '{print $2}']
additional: v4
os:v4
-----
machine:firefox
purpose:
language:v2
request:[output of result of ps -ef firefox | awk '{print $2}']
os:v4
-----
machine:helper
purpose:
language:v2
request:[output of result of ps -ef helper | awk '{print $2}']
os:v4
-----
another line

已尝试方案

用户尝试单独使用sed编写了如下命令:

gsed -r '/machine/,/os/ {/machine/ {s/.*?:\s*([^\s]+)/ps -ef | grep \1\n/e}; /request/ {s/.*?:\s*([^\s]+)//}}' filename

该命令无法正常达到预期效果,但可以执行ps -ef | grep [machinename]并将结果存储在缓冲区,想知道能否将缓冲区的值用于request字段的替换,以及具体实现方法。

解决方案

可以实现,更推荐使用awk完成,逻辑清晰不需要依赖GNU sed的非标准扩展,实现代码如下:

awk '
BEGIN { FS=":" }
/^-----$/ { in_block=0; print; next }
/^machine:/ { 
    in_block=1
    # 提取machine值,去除首尾空白
    machine_val=$2
    gsub(/^[ \t]+|[ \t]+$/, "", machine_val)
    # 执行命令获取对应PID,可根据实际需求调整命令内容
    cmd = "ps -ef | grep " machine_val " | grep -v grep | awk \'{print $2}\' | head -n1"
    cmd | getline req_val
    close(cmd)
    print $0
    next
}
# 块内匹配到request行直接替换输出
in_block && /^request:/ {
    print "request:" req_val
    next
}
# 其他行原样输出
{ print }
' your_file

如果一定要用GNU sed实现也可以通过hold空间暂存命令结果,但逻辑可读性远低于awk方案。你之前写的sed命令问题出在e标志会直接把替换后的内容作为命令执行,将原machine行直接替换为命令输出,不符合保留原machine行的要求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 14:24:02