我想将文本文件的选定部分按每列 9 字节对齐。
例如,假设我的文本文件如下所示。
00 2f c6 b8 29 fd 02 37 11 00 9f 74 34 0b 60 72 38 20 00 9e 61 33 8e ab 8a c0 09
00 fa f0 66 6d 0c 44 d6 24 00 a1 11 9d a2 13 a5 b3 83
我希望生成的文件是这样的
00 2f c6 b8 29 fd 02 37 11
00 9f 74 34 0b 60 72 38 20
00 9e 61 33 8e ab 8a c0 09
00 fa f0 66 6d 0c 44 d6 24
00 a1 11 9d a2 13 a5 b3 83
做到这一点最简单的方法是什么?是否有可能在bash
使用中做到这一点?sed
awk
或者更好的解决问题的方法是我已经格式化了我的输入序列,如下所示。
00 88 ec 40 bf 94 1d 63
f4 00 04 1c 4e 06 d0 2c
2e f9 00 90 03 51 d5 71
cc 86 79 00 24 6b 22 30
b6 66 0f 5f 00 c1 cd a5
c8 45 b9 88 85 00 c0 de
ae 47 d9 91 f9 d3 00 5b
即每行 8 个字节。如果您仔细注意到第 1 行中的第一个字节是00
。第 2 行中的第二个字节是00
,第 3 行中的第三个字节是00
。我想要对齐整个文件,以便所有行都以 a 开头00
。
답변1
无论单行有多少字节,这都将起作用
sed ':a $!N;s/\n/ /;ta;s/\(\(\([[:xdigit:]]\)\{2\} *\)\{8\}\([[:xdigit:]]\)\{2\}\) */\1\n/g'
输入
$ cat alignbyte
00 2f c6
b8 29 fd 02
37 11 00 9f 74 34 0b 60 72 38
20 00 9e 61 33 8e ab 8a c0 09
00 fa f0 66
6d 0c 44 d6 24
00 a1 11 9d a2 13 a5 b3 83
输出
$ sed ':a $!N;s/\n/ /;ta;s/\(\(\([[:xdigit:]]\)\{2\} *\)\{8\}\([[:xdigit:]]\)\{2\}\) */\1\n/g' alignbyte
00 2f c6 b8 29 fd 02 37 11
00 9f 74 34 0b 60 72 38 20
00 9e 61 33 8e ab 8a c0 09
00 fa f0 66 6d 0c 44 d6 24
00 a1 11 9d a2 13 a5 b3 83
我刚刚注意到,除了最后一组之外,您的输入文件在每组 9 个字节之后似乎都有两个空格。如果这是一个拼写错误并且所有组都是 9 个字节是确实由两个空格分隔,那么获得你想要的命令就是这样:
sed 's/ /\n/g' file
답변2
一种不关心输入的确切形状的方法是将其拆分为每行一个项目,然后将项目按所需数量分组。
tr -s '[:space:]' '\n' |
awk '
NR % 9 != 1 {printf " "}
{printf "%s", $0}
NR % 9 == 0 {print ""}
END {if (NR % 9) print ""}'
如果您不介意行尾有额外的空格,则可以awk
稍微简化代码:
tr -s '[:space:]' '\n' |
awk '
{printf "%s ", $0}
NR % 9 == 0 {print ""}
END {if (NR % 9) print ""}'
如果您的输入没有空行并且所有项目的宽度相同,那么有一个更简单的解决方案:将所有内容放在一行上,然后执行行折叠。
{ tr -s '\n' ' '; echo; } | fold -w 27
如果您有该fmt
实用程序,它可以结合这两个子任务:
fmt -w 27
답변3
一个基本技巧:
grep -o ".. .. .. .. .. .. .. .. .." your-file.txt
如果行长度可能不是 9 个十六字节的倍数,则删除 CRCL:
tr -d '\n\r' < your-file.txt | grep -o ".. .. .. .. .. .. .. .. .."
如果文件可能包含连续空格:
tr -s ' \n\r' ' ' < your-file.txt | grep -o ".. .. .. .. .. .. .. .. .."
我很欣赏复杂sed
/awk
编程的答案。
在这里,我提出使用基本工具的可读技巧。
답변4
awk '{gsub ("00","\n00") ;print $0}' myfile