Shell文本提取转换问题:从指定格式文件生成目标内容
Shell文本提取脚本修复方案
原始输入文件格式
id DiaMatch(32) = Sector(C26, 9, 1021) * Shift(k2, k2-p1, [], k3, -k3, [], k1, p1-k1, []); id DiaMatch(33) = Sector(C26, 9, 1021) * Shift(k2, k2-p1, [], k3, -k3, [], k1, p1-k1, []); id DiaMatch(34) = Sector(C10, 9, 1022) * Shift(k2, -p1+k1, [], k3, -k3, [], k1, p1-k2, []); id DiaMatch(35) = Sector(C10, 9, 1022) * Shift(k2, -p1+k1, [], k3, -k3, [], k1, p1-k2, []);
目标输出格式
file C26; replace_(k2, k2-p1, k3, -k3, k1, p1-k1); end; file C26; replace_(k2, k2-p1, k3, -k3, k1, p1-k1); end; file C10; replace_(k2, -p1+k1, k3, -k3, k1, p1-k2); end;
尝试的脚本
while read line; do sed -n '/shift/{s/.*\[(.*)\].*/\1/;s/\[//g;s/\]//g;p}' echo $line done < qqbz.match.info.inc
问题分析
- sed未接收输入:循环内的sed没有获取当前行
$line的内容,导致sed一直处于等待输入状态,无法处理每行文本。 - 正则表达式错误:原sed正则
.*\[(.*)\].*不符合文本结构——Shift后没有[符号,且基础sed不支持(.*)作为捕获组,需要启用扩展正则;同时目标内容里的[]是要剔除的无效项,不是包裹内容的标记。 - 缺失关键提取逻辑:脚本完全没处理
Sector(Cxx, ...)中的Cxx部分,这是生成file Cxx;的核心数据。 - 输出逻辑混乱:
echo $line直接输出原行,和目标格式要求完全不符。
解决方案
方案1:用awk一次性处理(推荐)
awk适合结构化文本提取,一行命令即可完成需求:
awk -F'[()]' '{ # 提取Sector中的Cxx标识 split($4, sec_arr, ","); file_tag = sec_arr[1]; # 提取Shift参数并剔除空的[]项 split($6, shift_arr, ","); replace_str = ""; for(i in shift_arr) { gsub(/^\s+|\s+$|\[\]/, "", shift_arr[i]); if(shift_arr[i] != "") { replace_str = replace_str (replace_str == "" ? "" : ", ") shift_arr[i]; } } # 输出目标格式内容 print "file " file_tag ";" print "replace_(" replace_str ");" print "end;" print "" }' qqbz.match.info.inc
方案2:改进while循环+sed
如果坚持用while循环,需修正sed调用和逻辑:
while read -r line; do # 提取Sector中的Cxx标识 file_tag=$(echo "$line" | sed -E 's/.*Sector\(([^,]+),.*/\1/') # 提取Shift参数并剔除[]无效项 replace_str=$(echo "$line" | sed -E 's/.*Shift\((.*)\);/\1/;s/\s*\[\]\s*,?//g;s/^\s+|\s+$//g') # 输出目标格式 echo "file $file_tag;" echo "replace_($replace_str);" echo "end;" echo "" done < qqbz.match.info.inc
以上两种方案均可正确提取所需内容并生成目标格式的输出。
内容的提问来源于stack exchange,提问作者Tanmoy Pati
相关产品推荐
相关产品推荐

