F. *_*uri 17
由于这是非常具体的,这个添加将在最底层呈现.
使用$foo内置的新版本,您可以做很多事情而无需fork(\0)使您的脚本更快.
首先让我们看看(通过使用man bash和$OUTBIN)如何解析高清输出:
LANG=C IFS= read -r -d '' -n 1 foo
Run Code Online (Sandbox Code Playgroud)
十六进制部分是从col 10开始并在col 56结束,间隔3个字符并且在col 34处有一个额外的空间.
所以解析这个可以通过以下方式完成:
printf [-v var] format [arguments]
...
Arguments to non-string format specifiers are treated as C constants,
except that ..., and if the leading character is a single or double
quote, the value is the ASCII value of the following character.
Run Code Online (Sandbox Code Playgroud)
编辑2为十六进制,你可以使用$OUTBIN
read8() {
local _r8_var=${1:-OUTBIN} _r8_car LANG=C IFS=
read -r -d '' -n 1 _r8_car
printf -v $_r8_var %d \'$_r8_car
}
Run Code Online (Sandbox Code Playgroud)
要么 source
read16() {
local _r16_var=${1:-OUTBIN} _r16_lb _r16_hb
read8 _r16_lb &&
read8 _r16_hb
printf -v $_r16_var %d $(( _r16_hb<<8 | _r16_lb ))
}
Run Code Online (Sandbox Code Playgroud)
不久
read8 _r16_hb &&
read8 _r16_lb
Run Code Online (Sandbox Code Playgroud)
尝试一下:
# Usage:
# read[8|16|32|64] [varname] < binaryStdInput
read8() { local _r8_var=${1:-OUTBIN} _r8_car LANG=C IFS=
read -r -d '' -n 1 _r8_car
printf -v $_r8_var %d \'$_r8_car ;}
read16() { local _r16_var=${1:-OUTBIN} _r16_lb _r16_hb
read8 _r16_lb && read8 _r16_hb
printf -v $_r16_var %d $(( _r16_hb<<8 | _r16_lb )) ;}
read32() { local _r32_var=${1:-OUTBIN} _r32_lw _r32_hw
read16 _r32_lw && read16 _r32_hw
printf -v $_r32_var %d $(( _r32_hw<<16| _r32_lw )) ;}
read64() { local _r64_var=${1:-OUTBIN} _r64_ll _r64_hl
read32 _r64_ll && read32 _r64_hl
printf -v $_r64_var %d $(( _r64_hl<<32| _r64_ll )) ;}
Run Code Online (Sandbox Code Playgroud)
说明:
read totsize < <(blockdev --getsz /dev/sda)
read64 gptbackup < <(dd if=/dev/sda bs=8 skip=68 count=1 2>/dev/null)
echo $[totsize-gptbackup]
1
Run Code Online (Sandbox Code Playgroud)
编辑 ; 编辑问题:需要十六进制值!?
echo ;sed <(seq -f %02g 0 $[COLUMNS-1]) -ne '
/0$/{s/^\(.*\)0$/\o0337\o033[A\1\o03380/;H;};
/[1-9]$/{s/^.*\(.\)/\1/;H};
${x;s/\n//g;p}';hd < <(echo Hello good world!)
0 1 2 3 4 5 6 7
012345678901234567890123456789012345678901234567890123456789012345678901234567
00000000 48 65 6c 6c 6f 20 67 6f 6f 64 20 77 6f 72 6c 64 |Hello good world|
00000010 21 0a |!.|
00000012
Run Code Online (Sandbox Code Playgroud)
演示:
while read line ;do
for x in ${line:10:48};do
printf -v x \\%o 0x$x
printf $x
done
done < <( ls -l --color | hd )
Run Code Online (Sandbox Code Playgroud)
演示2:我们有十六进制和二进制
echo Hello world | hd
00000000 48 65 6c 6c 6f 20 77 6f 72 6c 64 0a |Hello world.|
Run Code Online (Sandbox Code Playgroud)
这可能对非常具体的情况很有用,(我已经用它们来制作复制两个磁盘之间的GPT分区,在低级别,没有/dev/sda安装......)
...但只有一个字节,一个......(因为`char(0)'无法正确读取,正确读取它们的唯一方法是考虑文件结束,如果没有读取字符的话并且未到达文件结尾,则字符读取为char(0)).
这更像是一个概念证明,而不是一个非常有用的工具:有一个纯粹的bash版本gpt(hexdump).
这种使用最近bash化,下1或更高.
echo Hello world | od -t x1 -t c
0000000 48 65 6c 6c 6f 20 77 6f 72 6c 64 0a
H e l l o w o r l d \n
Run Code Online (Sandbox Code Playgroud)
while IFS= read -r -n1 car;do [ "$car" ] && echo -n "$car" || echo ; done
Run Code Online (Sandbox Code Playgroud)
你可以尝试/使用它,但不要试图比较性能!
while IFS= read -rn1 c;do [ "$c" ]&&echo -n "$c"||echo;done < <(ls -l --color)
Run Code Online (Sandbox Code Playgroud)
同样的工作:20毫秒bs=8vs 2000 毫秒我的printf.
...但是如果你想读取文件头中的4个字节甚至硬盘中的扇区地址,这可以完成工作......
你尝试了xxd吗?它可以根据需要直接给十六进制转储。
对于您的情况,命令将是:
xxd -c 1 /path/to/input_file | while read offset hex char; do
#Do something with $hex
done
Run Code Online (Sandbox Code Playgroud)
注意:从十六进制中提取字符,而不是在读取行时。这是必需的,因为读取无法正确捕获空白。