Linux Sh,awk:如何将shell中作为字符串可见的整数转换为16位低位/大端二进制整数?
我有一个bash序列Linux Sh,awk:如何将shell中作为字符串可见的整数转换为16位低位/大端二进制整数?,linux,bash,shell,awk,sh,Linux,Bash,Shell,Awk,Sh,我有一个bash序列 grep "integer =" $1 | awk -F= '{printf("%d\n",int($2*327))}' 过滤产生smth的物质,如: 6768 6572 6638 8403 8436 8436 8305 8502 但是,我需要将所有这些数字作为16位低端字或大端字(如果指定)放入二进制文件中。有什么好办法吗 理想情况下,它可能看起来像: grep integer=$1 | awk-F='{TO16BIT_LENDIANprintf%d\n,int$2*
grep "integer =" $1 | awk -F= '{printf("%d\n",int($2*327))}'
过滤产生smth的物质,如:
6768
6572
6638
8403
8436
8436
8305
8502
但是,我需要将所有这些数字作为16位低端字或大端字(如果指定)放入二进制文件中。有什么好办法吗
理想情况下,它可能看起来像:
grep integer=$1 | awk-F='{TO16BIT_LENDIANprintf%d\n,int$2*327}'>>out.bin这应该可以:
cat $1 | grep "integer =" | awk -F='
function out(b)
{
if(b==0)
{
system("printf \"\\00\"");
}
else
{
printf("%c",b);
}
}
function shortToLE(n)
{
n%=65536;
msb=n/256;
lsb=n%256;
out(lsb);
out(msb);
}
{
shortToLE($2*327)
}
' >> out.bin
以及去除无用的cat和grep的优化方法:
awk -F" =" '
function out(b)
{
if(b==0)
{
system("printf \"\\00\"");
}
else
{
printf("%c",b);
}
}
function shortToLE(n)
{
n%=65536;
msb=n/256;
lsb=n%256;
out(lsb);
out(msb);
}
$1 == "integer" {
shortToLE($2*327)
}
' $1 >> out.bin
使用特定格式写入文件通常使用高级语言完成。Ruby的一个示例,其中输入文件为$1: Ruby的Arraypack方法已被记录在案 更新: 使用-n开关:
现在让我们来看看这个丑陋的事实:使用printf%c的脚本,数据不再工作 这是我那该死的丑陋的解决办法。啊
# This ugly hack forces our broken system to pretend it works
MAGIC_SHIT=((ENVIRON[LANG]=="C")?0:0xd800);
function TO16BIT_LENDIAN(n){return sprintf("%c%c",(MAGIC_SHIT+and(n,0xff)),(MAGIC_SHIT+rshift(and(n,0xff00),8)));}
这里可能需要一些解释。
当我们编写脚本时,假设
export LANG=C
一切就绪。然而,当一个人
en_US.UTF-8
然后POSIX正确性开始生效,您现在不再能够像以前那样处理字节,而是被迫将每个字符视为最小的单元。
这意味着
0x00 up to 0x7f = 0xYY // sprintf("%c",n) prints ok
0x80 up to 0xbf = 0xc2 0xYY // sprintf("%c",n) prints 0xc2 in front
0xc0 up to 0xff = 0xc3 + 0x80..0xb0 // Totally junk, not what we want.
您现在无法再打印128字节的原始字节
现在,这是因为UTF-8规范告诉我们这样做。
这是最重要的部分
大多数在utf-8字符代码之间转换的用户执行简单的位操作
这样做。
当我们将0xd800或grater值提供给这些PRSER时,大多数情况下,在未记录特性的情况下,允许您像在旧系统上一样打印原始字节
这完全是一个丑陋的黑客,你不应该依赖它。据我所知,没有这样的规范存在,或是我一时糊涂。请告诉我有没有这样的
但是,当您在一个具有错误LANG值的系统上时,或者当您的脚本需要在脚本的大部分(仅数据输出除外)上处理utf-8字符时,可以将其视为临时解决方案,直到我们能够在脚本中设置LANG或equalvant为止
最后一次检查是在gawk 4.0.1上
我讨厌这种黑客行为。是否要在.bin中用新行分隔输出?2.Perl可能有一些东西可以按照您的设想做到这一点。如果使用您提出的工具可以做到这一点,我会感到惊讶。3.对于这样简单的事情,您可以编写C语言代码。也许为大端和小端制作2个9月的节目。4.祝你好运@Shelleter:1.不,只是一个字节流。2.嗯,可能是python,但如果可能的话,我想继续使用awk/bash。3.python-c Blablabla可能更好,因为避免了编译。4.谢谢!该死!你赢了我。但是,您可以去掉cat,只需将文件名放在awk命令的末尾。您还可以通过在awk中搜索integer=来摆脱grep,然后使用index和substr删除integer=部分。最后,只剩下一个awk程序。尽管这只猫没用,我还是会给你+1。谢谢你指出这一点。我太专注于有点棘手的awk部分,而忽略了它周围的东西,我基本上只是剪切和粘贴。将优化的方式添加到我的回复中。使用ruby可能看起来不那么混乱-ne@glenn:是否有理由将其写入文件而不是标准输出?@ninjalj,这是问题的一个要求。@glenn:我认为不需要用一种语言来完成所有工作,只要将标准输出重定向到文件,这就是-n和-p的作用,使一个衬里与外壳一起使用。
en_US.UTF-8
0x00 up to 0x7f = 0xYY // sprintf("%c",n) prints ok
0x80 up to 0xbf = 0xc2 0xYY // sprintf("%c",n) prints 0xc2 in front
0xc0 up to 0xff = 0xc3 + 0x80..0xb0 // Totally junk, not what we want.