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

如何用正则提取脚本输出中各文件名对应的首个内存地址?

问题描述

我有一段脚本返回的如下文本:

7d60f000-7d67b000 r-xp 00000000 fb:00 11         /bin/busybox.nosuid
7d68b000-7d68c000 r--p 0006c000 fb:00 11         /bin/busybox.nosuid
7d68c000-7d68d000 rw-p 0006d000 fb:00 11         /bin/busybox.nosuid
b3dfb000-b3ebe000 r-xp 00000000 fb:00 1636       /lib/libc-2.31.so
b3ebe000-b3ecd000 ---p 000c3000 fb:00 1636       /lib/libc-2.31.so
b3ecd000-b3ecf000 r--p 000c2000 fb:00 1636       /lib/libc-2.31.so
b3ecf000-b3ed1000 rw-p 000c4000 fb:00 1636       /lib/libc-2.31.so
b3ed1000-b3ed3000 rw-p 00000000 00:00 0
b3ed3000-b3f24000 r-xp 00000000 fb:00 1655       /lib/libm-2.31.so
b3f24000-b3f33000 ---p 00051000 fb:00 1655       /lib/libm-2.31.so
b3f33000-b3f34000 r--p 00050000 fb:00 1655       /lib/libm-2.31.so
b3f34000-b3f35000 rw-p 00051000 fb:00 1655       /lib/libm-2.31.so
b3f35000-b3f36000 r-xp 00000000 fb:00 4296       /usr/lib/libcrashlog.so.0.0.0
b3f36000-b3f45000 ---p 00001000 fb:00 4296       /usr/lib/libcrashlog.so.0.0.0
b3f45000-b3f46000 r--p 00000000 fb:00 4296       /usr/lib/libcrashlog.so.0.0.0
b3f46000-b3f47000 rw-p 00001000 fb:00 4296       /usr/lib/libcrashlog.so.0.0.0
b3f47000-b3f5d000 r-xp 00000000 fb:00 1628       /lib/ld-2.31.so
b3f6b000-b3f6d000 rw-p 00000000 00:00 0
b3f6d000-b3f6e000 r--p 00016000 fb:00 1628       /lib/ld-2.31.so
b3f6e000-b3f6f000 rw-p 00017000 fb:00 1628       /lib/ld-2.31.so

我想要为每个文件名提取对应的首个内存地址,例如:

  • 对于/bin/busybox.nosuid,返回7d60f000-7d67b000
  • 对于/lib/libc-2.31.so,返回b3dfb000-b3ebe000
  • 对于/lib/libm-2.31.so,返回b3ed3000-b3f24000
  • 对于/usr/lib/libcrashlog.so.0.0.0,返回b3f35000-b3f36000
  • 对于/lib/ld-2.31.so,返回b3f47000-b3f5d000

请问是否可以通过正则表达式实现这一需求?

解决方案

完全可以通过正则表达式配合简单的去重逻辑实现需求,以下是具体实现方案:

核心思路

  1. 正则匹配规则:每行开头的内存地址是[0-9a-f]+-[0-9a-f]+格式的字符串,文件名在每行末尾。可以用正则捕获这两个关键部分:^([0-9a-f]+-[0-9a-f]+).*?(\/[\w\/\.-]+)$
    • ^([0-9a-f]+-[0-9a-f]+):捕获行首的内存地址段
    • .*?:非贪婪匹配中间的任意字符
    • (\/[\w\/\.-]+)$:捕获行末的完整文件名
  2. 去重处理:同一个文件会出现多次,只需记录首次捕获到的内存地址即可。

具体实现示例

用awk实现(轻量高效)

直接用awk的数组去重,一行代码就能搞定:

awk '!seen[$NF]++ {print "对于`" $NF "`,返回`" $1 "`"}' input.txt

解释:

  • $NF表示每行最后一个字段(即文件名)
  • !seen[$NF]++:仅当文件名第一次出现时执行后续打印操作
  • print语句按照需求格式输出结果

用Python实现(灵活可控)

如果需要更复杂的后续处理,用Python结合正则实现:

import re

record = {}
# 定义匹配正则
pattern = re.compile(r'^([0-9a-f]+-[0-9a-f]+).*?(\/[\w\/\.-]+)$')

# 读取并处理每行内容
with open('input.txt', 'r') as f:
    for line in f:
        line = line.strip()
        if not line:
            continue
        match_result = pattern.match(line)
        if match_result:
            addr = match_result.group(1)
            fname = match_result.group(2)
            # 仅记录首次出现的地址
            if fname not in record:
                record[fname] = addr

# 按需求格式输出
for fname, addr in record.items():
    print(f"对于`{fname}`,返回`{addr}`")

输出结果

运行上述任意一种方法,都会得到你需要的结果:

  • 对于/bin/busybox.nosuid,返回7d60f000-7d67b000
  • 对于/lib/libc-2.31.so,返回b3dfb000-b3ebe000
  • 对于/lib/libm-2.31.so,返回b3ed3000-b3f24000
  • 对于/usr/lib/libcrashlog.so.0.0.0,返回b3f35000-b3f36000
  • 对于/lib/ld-2.31.so,返回b3f47000-b3f5d000

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:12:03