我需要劫持并修改数据流。该流由固定宽度命令组成。每个命令都是一个新行,文档说每个命令以STX
/ ETX
对开始和结束(文本的开头和结尾)
发送系统正在使用串行,但受到攻击的iPocket设备通过IP与我们的PBX进行通信。据我所知,它只是将串口转换为telnet,这应该让事情变得非常简单。
我需要查找的字符串以NAM
开头。结构是这样的:
STX NAM EXT# LASTNAME,FIRSTNAME ETX
我需要用空格替换,FIRSTNAME
,这样就不会改变命令的长度。
我一直在尝试以下操作,虽然它根据需要在两个方向上将数据端到端传递,并删除了所需的数据,但它不会保持命令的长度。
ipocket <-> nc -kl 1100 | sed 's/,[^,]*/ /g' | nc target_ip target_port <-> PBX
我将使用Linux机器箱完成此任务。我有理由相信这可以在perl或python中完成,但我还没有一个线索从哪里开始。任何帮助将不胜感激!
答案 0 :(得分:2)
这应该这样做,它是一个单线
perl -pe '/^STX\s\w+\s\d+#\s\w+,(\w+)\sETX$/;$len=length($1);s/$1/" " x $len/e'
我测试过使用。
echo "STX NAM 100# LASTNAME,FIRSTNAME ETX" | perl -pe '/^STX\s\w+\s\d+#\s\w+,(\w+)\sETX$/;$len=length($1);s/$1/" " x $len/e'
然后返回
STX NAM 100# LASTNAME, ETX
确保字符串与我测试的长度相同。
echo "STX NAM 100# LASTNAME,FIRSTNAME ETX" | perl -pe '/^STX\s\w+\s\d+#\s\w+,(\w+)\sETX$/;$len=length($1);s/$1/" " x $len/e'| perl -pe 'print length($_);'
给予36。
echo "STX NAM 100# LASTNAME,FIRSTNAME ETX"|perl -pe 'print length($_);'
给予36。
答案 1 :(得分:0)
在Perl中,添加检查字符串以NAM
启动并真正替换,FIRSTNAME
:
nc -kl 1100 | \
perl -pe '/^STX NAM / && do { s/(,FIRSTNAME)/" " x length("$1")/ge }' | \
nc <...>
在Perl中s///e
按预期进行替换,但将替换字符串计算为e
xpression。运算符x
生成一个新字符串,在右侧给出的左侧重复字符串。显然不会修改不匹配的字符串。
答案 2 :(得分:0)
您可以使用以下命令代替sed
命令:
perl -pe 's/(,\w+)/" " x length $1/ge'
替换上的e
选项意味着s///
的右侧被评估为Perl表达式。在这种情况下,表达式将根据捕获的匹配的长度返回正确的空格数。
答案 3 :(得分:0)
是的,iPocket会对数据进行原始传递。这些选项通常用于输入数据的打包,这实际上不会影响您在此处尝试执行的操作。 (我为该设备编写了固件。)
但是,此处的命令行答案都不起作用,因为它们是基于行的,而您的数据不是。也就是说,数据流中的换行符sed
和perl
用作“数据包”边界。
我不相信你有任何办法可以从命令行完成这项工作。您将不得不编写一个简单的程序来读取传入的TCP流,查找STX / ETX框架,根据需要替换字符,然后将数据写入另一端。 (不要忘记通过后方方向。)
Python可能是最简单的方法。
答案 4 :(得分:-1)
这是sed
版本:
sed 'h;s/[^,]*,\([^ ]*\) ETX/\1/;s/./ /g;x;s/,.*/,/;G;s/\n//;s/$/ ETX/'
我愿意打赌,不仅命令固定宽度,而且字段也是固定宽度。如果是这种情况,那么这样的事情可能会起作用:
sed 's/\(.\{22\}\).\{9\}\(.\{4\}\)/\1 \2/'
或
sed -r 's/(.{22}).{9}(.{4})/\1 \2/'
或
sed -r 's/STX (.{18}).{9} ETX/STX \1 ETX/'