如何从含十六进制的混合文本中提取完整目标子串?
问题需求
从带有行尾空格的输入文本中提取目标子串,具体如下:
输入文本
42 45 47 49 4e 21 40 23 47 68 6a 6b 2c 47 68 6a BEGIN!@#Ghjk,Ghj 6b 45 4e 44 23 40 21 kEND#@!
期望输出
BEGIN!@#Ghjk,GhjkEND#@!
注:输入行尾存在空格,无法手动去除
已尝试的Bash脚本及问题
使用以下脚本仅能提取到部分内容:
#!/bin/bash s=$(awk '/BEGIN!@#/,/END#@!/' switch.log ) while IFS= read -r line do h=$(echo "$line" | awk '{$1=$1;print}') for i in {0..100} do zzz=$(echo "$h" | awk '{print $(NF-$i)}') if [ ! -z "$zzz" -a "$zzz" != " " ]; then hh=$(echo "$h" | awk '{print $(NF-$i)}') echo "$zzz" echo -e "$zzz" >> ggg.txt break fi done done <<< "$s"
实际输出
BEGIN!@#Ghjk,Ghj
原脚本仅提取了BEGIN!@#起始的单个字段,未处理中间十六进制转字符及拼接END#@!的逻辑,导致结果不完整。
可行解决方案
方案1:sed + grep组合处理
sed -E 's/ 6b /k/g; s/(BEGIN!@#.*) k(END#@!)/\1\2/' switch.log | grep -o 'BEGIN!@#.*END#@!'
逻辑说明:
s/ 6b /k/g:将输入中十六进制的6b(空格包裹)替换为对应ASCII字符ks/(BEGIN!@#.*) k(END#@!)/\1\2/:去除BEGIN与END#@!之间多余的kgrep -o 'BEGIN!@#.*END#@!':精准提取从BEGIN!@#到END#@!的完整子串
方案2:awk单命令处理
awk '{ gsub(/ 6b /, "k") match($0, /BEGIN!@#.*END#@!/) res = substr($0, RSTART, RLENGTH) gsub(/ k(END#@!)/, "\1", res) print res }' switch.log
逻辑说明:
- 替换十六进制
6b为字符k - 匹配
BEGIN!@#到END#@!的完整区间 - 提取匹配内容并去除多余的
k - 输出最终结果
内容的提问来源于stack exchange,提问作者ahmed ahmed
相关产品推荐
相关产品推荐

