Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux Sh,awk:如何将shell中作为字符串可见的整数转换为16位低位/大端二进制整数?_Linux_Bash_Shell_Awk_Sh - Fatal编程技术网

Linux Sh,awk:如何将shell中作为字符串可见的整数转换为16位低位/大端二进制整数?

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*

我有一个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*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.