简介这是一套面向GNSS数据质量分析人员的Anubis批处理增强工具针对原版Anubis仅能处理单日多站、每次需手动修改配置文件的痛点实现了多天多站数据的自动化批量处理适合测绘、地壳形变监测、时间同步等领域的科研人员与工程师使用。压缩包共56个文件约90.6MB包含可执行程序、批处理脚本、Python绘图脚本、配置文件及示例观测数据与参考结果涵盖21o、21n、xtr、xqc等GNSS常用数据格式并附有使用录屏与必读说明文档便于快速上手。目前已有822人学习下载。借助其中的批处理脚本与绘图程序读者可一次性完成多天多站的数据质量检核与结果出图省去重复改配置的繁琐流程同时示例数据与参考结果可用于对照验证帮助理解Anubis的输入输出结构与批处理调用逻辑显著提升批量数据处理的效率与规范性。1. 从一次多天多站数据积压说起run_anubis 批处理到底解决什么问题如果你手头有一批 GNSS 观测数据覆盖多个测站、连续多天而处理工具是 Anubis那你大概率经历过这样的场景手动改配置、逐天逐站跑、跑完再手动整理输出。站点少的时候还能忍一旦站点上到两位数、天数跨过一周重复劳动量就会指数级上升。run_anubis_批处理_多天多站这个标题说的就是用批处理脚本把 Anubis 的多天多站处理流程串起来让机器替你循环你只负责检查结果。它适合做 GNSS 数据质量分析、多站长期监测、科研数据预处理的从业者也适合任何需要把 Anubis 从单次手动升级成批量自动的人。核心思路不复杂用一层外层循环遍历测站内层循环遍历日期每次调用 Anubis 处理单站单天最后统一收集日志和报告。但真正落地时路径拼接、日期格式、配置文件模板、输出目录管理这几个环节每一个都能让你翻车。2. 批处理驱动 Anubis 的底层逻辑与目录规划2.1 为什么选批处理而不是手动或纯 PythonAnubis 本身是一个命令行程序接受配置文件作为输入输出质量分析报告。它的调用方式天然适合被脚本包裹。选择批处理Windows 下.batLinux 下.sh而不是纯 Python 的理由很实际部署环境往往没有 Python或者 Python 版本混乱而批处理在任何 Windows 机器上双击就能跑在 Linux 上也不需要额外依赖。另一个原因是 Anubis 的官方发行包里本身就带了RunAnubisAndPlot.exe这类封装工具说明作者也预期用户会做批量调用。批处理做循环、拼路径、调外部程序虽然语法粗糙但胜在稳定、可移植、不需要运行时。常见做法是外层用批处理做站点和日期的双重循环内层调用 Anubis 可执行文件传入当天当站的配置文件。配置文件本身可以用模板加变量替换生成也可以提前为每个站每天准备好。前者灵活但脚本复杂后者简单但文件多。我一般会选模板替换因为站点和日期是变量硬编码配置文件数量会爆炸。2.2 目录结构怎么摆才不乱多天多站处理最容易失控的地方是输出文件散落。建议在开始写脚本之前先把目录结构定死。一个可靠的布局是这样的project_root/ ├── data/ │ ├── STA1/ │ │ ├── 2024DOY001/ │ │ │ └── sta1_001.24o │ │ └── 2024DOY002/ │ │ └── sta1_002.24o │ └── STA2/ │ └── ... ├── config/ │ ├── template.cfg │ └── generated/ ├── output/ │ ├── STA1/ │ │ ├── 2024DOY001/ │ │ └── 2024DOY002/ │ └── STA2/ ├── logs/ └── run_anubis.bat这个结构的关键点是数据按站按天分目录配置模板单独放生成的配置和输出按站按天镜像。这样出问题的时候你能直接定位到某站某天的输入、配置和输出不需要在一堆文件里翻找。批处理脚本里所有路径都基于project_root做相对拼接换机器的时候只需要改一个根路径变量。2.3 日期循环的写法与自增陷阱批处理的for循环做日期自增是一个经典坑。很多人用for /l %%d in (1,1,31)来遍历天但 DOY年积日不是简单的 1 到 31月份天数不同闰年还要加一天。更稳妥的做法是提前生成一个日期列表文件每行一个 DOY 字符串然后批处理逐行读取。这样日期逻辑在脚本外面处理批处理只负责读和循环。echo off setlocal enabledelayedexpansion set ROOTD:\gnss_project set ANUBISD:\tools\anubis\anubis.exe set STATIONSSTA1 STA2 STA3 set DOY_LIST%ROOT%\config\doy_list.txt for %%S in (%STATIONS%) do ( for /f tokens1 delims %%D in (%DOY_LIST%) do ( set CUR_STA%%S set CUR_DOY%%D set IN_DIR%ROOT%\data\%%S\%%D set OUT_DIR%ROOT%\output\%%S\%%D set CFG%ROOT%\config\generated\%%S_%%D.cfg if not exist !OUT_DIR! mkdir !OUT_DIR! echo [INFO] Processing !CUR_STA! !CUR_DOY! %ANUBIS% -c !CFG! -o !OUT_DIR! %ROOT%\logs\run.log 21 if errorlevel 1 ( echo [ERROR] Failed: !CUR_STA! !CUR_DOY! %ROOT%\logs\error.log ) ) ) endlocal这段脚本的逻辑说明外层for %%S遍历站点列表内层for /f逐行读取 DOY 列表。enabledelayedexpansion和!变量!是必须的因为循环体内对变量的修改需要延迟展开才能生效否则%OUT_DIR%会在循环开始前就被替换成空值。errorlevel判断用来捕获 Anubis 返回的非零退出码把失败记录单独写到error.log方便事后排查。参数方面-c指定配置文件-o指定输出目录具体参数名以你手头 Anubis 版本的帮助信息为准不同编译版本可能有差异。注意for /f读取的文件如果最后一行没有换行符某些 Windows 版本会漏掉最后一行。生成doy_list.txt时确保末尾有空行。3. 配置文件模板替换与 Anubis 调用参数3.1 模板里哪些字段必须动态替换Anubis 的配置文件通常包含输入文件路径、输出路径、测站名、时间范围、分析选项等。多天多站场景下必须动态替换的字段至少有三个输入观测文件路径、输出目录、测站标识。其余分析参数如高度角截止、采样率、周跳检测阈值可以固定也可以按站按天覆盖。一个典型的模板片段[INPUT] obs_file {{OBS_FILE}} station {{STATION}} [OUTPUT] out_dir {{OUT_DIR}} report quality_report.txt [PROCESSING] elevation_cutoff 10 sampling_interval 30用批处理做替换最简单的方式是用sedLinux或 PowerShell 的-replaceWindows。如果坚持纯批处理可以用for /f逐行读取模板遇到占位符就替换然后输出到生成目录。但纯批处理做字符串替换很啰嗦我一般会在 Windows 下用一段内联 PowerShellpowershell -Command (Get-Content %ROOT%\config\template.cfg) -replace {{OBS_FILE}},!IN_DIR!\sta.obs -replace {{STATION}},!CUR_STA! -replace {{OUT_DIR}},!OUT_DIR! | Set-Content !CFG!这行命令的逻辑是读取模板文件依次替换三个占位符写入生成的配置文件。参数说明{{OBS_FILE}}替换为实际观测文件路径{{STATION}}替换为当前站名{{OUT_DIR}}替换为输出目录。注意路径中的反斜杠在 PowerShell 字符串里不需要转义但如果路径含空格需要确保变量本身带引号。3.2 调用 Anubis 时的参数与退出码处理Anubis 的调用参数在不同版本间可能有差异但核心模式是固定的指定配置文件、指定输出位置、可能还有日志级别。调用时最容易忽略的是工作目录。如果 Anubis 内部用相对路径引用某些辅助文件而你的批处理没有cd到正确目录就会报文件找不到。稳妥做法是在调用前pushd到输出目录或项目根目录调用完popd。pushd %OUT_DIR% %ANUBIS% -c %CFG% -o . %ROOT%\logs\%%S_%%D_stdout.log 21 set RC%errorlevel% popd if %RC% neq 0 ( echo [FAIL] %CUR_STA% %CUR_DOY% return code %RC% %ROOT%\logs\error.log )这里把 stdout 和 stderr 都重定向到按站按天命名的日志文件而不是全部追加到一个大日志里。这样做的好处是排查问题时直接打开对应日志不需要在几千行里搜索。RC变量保存退出码非零时记录到错误日志。参数方面-o .表示输出到当前目录配合pushd就等价于输出到OUT_DIR。3.3 多站多天下的并发与资源控制批处理默认是串行的一个站一天处理完再处理下一个。如果站点和天数都很多总耗时可能很长。Anubis 本身是单线程的但你可以同时跑多个 Anubis 实例来利用多核。做法是用start /b在后台启动然后用一个计数器控制并发数。不过并发带来两个问题磁盘 I/O 争抢和日志交错。如果数据在机械硬盘上并发反而可能变慢。我一般会先串行跑一遍小批量测出单站单天耗时再决定是否并发。set MAX_CONCURRENT4 set /a RUNNING0 for %%S in (%STATIONS%) do ( for /f tokens1 delims %%D in (%DOY_LIST%) do ( if !RUNNING! geq %MAX_CONCURRENT% ( waitfor /t 1 dummy 2nul set /a RUNNING-1 ) start /b cmd /c process_one.bat %%S %%D set /a RUNNING1 ) )这段脚本用RUNNING计数器控制同时运行的任务数超过上限就等待。waitfor是一个粗糙的同步手段实际项目中更可靠的做法是用任务计划或第三方并发工具。参数MAX_CONCURRENT建议设为 CPU 核心数的一半到全部取决于磁盘速度。如果输出目录在同一块盘上并发数不要超过 4否则 I/O 等待会吃掉并行收益。4. 避坑与排查多天多站批处理最容易翻车的五个地方4.1 现象部分天处理成功部分天报文件不存在原因通常是日期列表里的 DOY 格式和实际数据目录名不一致。比如列表里写的是2024001而目录名是2024DOY001或者反过来。另一种可能是观测文件命名规则不统一某些天用了.24o某些天用了.obs。批处理不会帮你做模糊匹配路径拼出来是什么就是什么。解决在生成doy_list.txt之前先用脚本扫描data/目录把实际存在的目录名提取出来作为列表。观测文件同理用dir /b或ls确认扩展名一致。如果确实不统一在批处理里加一层判断按优先级尝试多个扩展名。4.2 现象Anubis 返回 0 但输出目录是空的Anubis 返回 0 只表示程序正常退出不表示分析成功。如果配置文件里的输入路径指向了一个空文件或不存在的文件某些版本的 Anubis 会静默跳过不报错也不输出。这是最阴险的坑因为你的错误日志里什么都没有但结果就是缺了几天。解决在批处理里加一个后置检查处理完成后判断输出目录里是否有预期的报告文件。如果没有即使退出码为 0 也记录为异常。if not exist %OUT_DIR%\quality_report.txt ( echo [WARN] No report generated: %CUR_STA% %CUR_DOY% %ROOT%\logs\error.log )4.3 现象路径含空格或中文导致 Anubis 崩溃Windows 下路径含空格是常态但很多命令行程序对带空格的参数处理不好。如果你的项目根目录是D:\GNSS 项目\批处理拼接出来的路径就带空格Anubis 可能把空格前后的内容当成两个参数。中文路径更麻烦某些编译版本的 Anubis 对非 ASCII 路径支持不完整。解决项目根目录和所有子目录都用纯英文、无空格的命名。如果无法避免确保所有路径变量在传给 Anubis 时都用双引号包裹。批处理里%ANUBIS% -c %CFG%这种写法是必须的不要图省事省略引号。4.4 现象日志文件被并发写入导致内容交错如果你用了并发多个 Anubis 实例同时往同一个日志文件追加内容日志就会交错排查时根本读不了。即使每个实例写自己的日志如果日志文件名只按站命名而不按天命名同站不同天的并发也会冲突。解决日志文件名必须包含站名和 DOY确保全局唯一。如果并发数大于 1绝对不要共用日志文件。另外重定向在 Windows 下不是原子操作高并发时仍可能交错建议每个任务写独立文件最后再合并。4.5 现象批处理在 Win7 上跑正常在 Win10 上报语法错误Win7 和 Win10 的cmd.exe在某些语法支持上有差异尤其是for /f的选项和延迟展开的行为。另外Win10 默认的代码页可能是 936 或 65001如果脚本文件保存为 UTF-8 带 BOMcmd会把 BOM 当成命令的一部分导致第一行报错。解决脚本文件保存为 ANSI 编码Windows 下或 UTF-8 无 BOM。如果需要在 Win7 和 Win10 之间迁移避免使用太新的语法特性比如for /f的usebackq选项在某些旧版本上行为不一致。最稳妥的做法是在目标机器上先跑一个最小测试脚本确认基本语法没问题再上完整流程。5. 从能跑到好用结果校验与增量处理的两个技巧批处理跑通只是第一步真正让这套方案值得投入的是结果校验和增量处理。多天多站跑完之后你面对的是几十上百个输出目录手动检查不现实。我一般会写一个汇总脚本把所有quality_report.txt里的关键指标提取出来生成一张 CSV 表按站按天排列。这样一眼就能看出哪天哪个站的数据异常。import os import csv import re root rD:\gnss_project\output rows [] for sta in os.listdir(root): sta_dir os.path.join(root, sta) if not os.path.isdir(sta_dir): continue for doy in os.listdir(sta_dir): report os.path.join(sta_dir, doy, quality_report.txt) if not os.path.isfile(report): rows.append([sta, doy, MISSING, , ]) continue with open(report, r, encodingutf-8, errorsignore) as f: text f.read() obs_count re.search(rTotal observations:\s*(\d), text) gap_count re.search(rData gaps:\s*(\d), text) rows.append([ sta, doy, obs_count.group(1) if obs_count else N/A, gap_count.group(1) if gap_count else N/A, OK ]) with open(summary.csv, w, newline, encodingutf-8) as f: writer csv.writer(f) writer.writerow([station, doy, obs_count, gap_count, status]) writer.writerows(rows)这段 Python 脚本的逻辑是遍历输出目录按站按天读取质量报告用正则提取观测总数和数据缺口数写入 CSV。参数说明root是输出根目录正则表达式Total observations和Data gaps需要根据你实际报告里的字段名调整。如果报告里没有这些字段就换成你关心的指标。errorsignore是为了防止报告文件里有非 UTF-8 字符导致读取失败。增量处理是另一个实用技巧。如果昨天跑了 100 个站天组合今天只新增了 5 个没必要全部重跑。做法是在输出目录里放一个标记文件比如.done批处理在调用 Anubis 之前先检查这个文件是否存在存在就跳过。这样即使你中途中断重新运行也只会处理未完成的部分。if exist %OUT_DIR%\.done ( echo [SKIP] Already done: %CUR_STA% %CUR_DOY% %ROOT%\logs\skip.log goto :next ) %ANUBIS% -c %CFG% -o %OUT_DIR% %ROOT%\logs\%%S_%%D_stdout.log 21 if %errorlevel% equ 0 ( echo done %OUT_DIR%\.done ) :next这个模式的关键是只有 Anubis 成功返回且输出文件存在时才写.done标记。如果中途失败标记不存在下次重跑会自动重试。参数方面.done文件的内容无关紧要存在即可。如果你需要记录处理时间可以把时间戳写进去。我自己在这套流程上踩过最深的坑是早期没有做增量标记每次调试都全量重跑一个下午跑了七遍同样的数据。后来加了.done检查调试效率直接翻倍。另一个习惯是每次修改批处理脚本后先用一个站一天的数据做冒烟测试确认路径拼接和 Anubis 调用都正常再放开全量。这个习惯帮我省下了无数次跑了两小时才发现配置模板里少了个变量的后悔药。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
C# USB HID读卡器上位机开发:IC卡与CPU卡稳定通信实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:24:09
CST共面波导色散曲线仿真:本征模求解器设置与后处理全流程 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:24:03
DMA方式深度解析:从总线仲裁到408真题解题思路 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 1:24:03
Spingboot启动预热的实现 启动预热的适用场景启动预热适合以下情况:数据主要来自第三方接口,无法直接从本地数据库读取。第三方接口响应较慢,首次访问容易超时。一个页面需要调用多个第三方接口或逐项查询。数据读取频繁,但变化不频繁。希望服务启动后&… · 2026/9/28 3:40:12
学Java别走弯路,这5个方向最吃香 学Java的人很多,但学明白的人不多。有人学了半年还在写控制台程序,有人一年就能独当一面。差别不在天赋,而在方向。Java生态太庞大了,什么都学等于什么都没学。选对方向,事半功倍。今天盘点当前最吃香的5个Java方向&am… · 2026/9/28 3:32:15
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01
制作网页比较方便的软件怎么选?一文搞懂避坑指南 制作网页比较方便的软件怎么选?一文搞懂避坑指南 很多老板一上来就问:做个网站多少钱?但我反问他:你的域名买了吗?服务器租了吗?他一脸懵。这就是典型的“域名服务器搞不懂”。别急,今天咱们不聊虚的,直接 一文搞懂 那些让你头秃的技术名词。… · 2026/9/28 0:00:06
婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量 婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量 找婚恋网站建站公司,最怕的就是被坑高价。很多同行跟我吐槽,报价单上写得模棱两可,功能栏里全是“高级定制”、“专属UI”,结果落地全是套壳。今天不聊虚的,直接甩几个我经手的 实战案例… · 2026/9/28 0:00:19
济南做网站多少钱:3个案例拆解,防黑源码下载全攻略 济南做网站多少钱:3个案例拆解,防黑源码下载全攻略 上周济南一个做建材的老板找我,脸都绿了。他的官网首页弹出了赌博广告,后台被植入了挖矿脚本。他慌得问我:“网站被黑挂马不知道怎么办?能不能直接找之前的外包公司要源码下载,看看哪里被动了手脚?… · 2026/9/28 0:00:25