我只想将文件的前64个字符与同一个二进制文件的最后64个字符交换。
我该怎么做?
答案 0 :(得分:0)
我不确定这是否可以用sed或awk可靠地完成。我可以想象一个可以在特定文件上工作的解决方案,或者某些奇怪的条件,例如可能出现换行符。
这在C中相当容易。如果不限于sed或awk,也可以使用shell命令完成:
n=64
f=/tmp/test
eval $(stat -s $f)
e=$(($st_size - $n))
dd bs=1 count=$n if=$f iseek=$e of=/tmp/last64
dd bs=$n count=1 if=$f of=/tmp/first64
dd bs=1 count=$n if=/tmp/first64 seek=$e of=$f conv=notrunc
dd bs=$n count=1 if=/tmp/last64 of=$f conv=notrunc
答案 1 :(得分:0)
使用xxd
:
n=64
file=data
tmp=tmp
len=$(wc -c < "$file")
offset=$((len - n))
len=$((offset - n))
xxd -s -$n "$file" | xxd -r -s -$offset > "$tmp"
xxd -s $n -l $len "$file" | xxd -r >> "$tmp"
xxd -l $n "$file" | xxd -r >> "$tmp"
mv "$tmp" "$file"
修改强>
另一种方法是使用xxd
和sed
:
n=64; hd=$((n * 2))
file=data
tmp=tmp
xxd -c $n -p "$file" |
sed "1{x;d};:a;N;s/\n//;\${s/\(.*\)\(.\{$hd\}\)\$/\2\1/;G};ba" |
xxd -r -p > "$tmp"
mv "$tmp" "$file"
而不是六次调用xxd
,而是xxd
的两次调用,sed
的一次调用(以及更少的文件读取和写入)。
sed
命令的说明:
1{x;d}
- 保存保留空间中的第一行十六进制数字。使用-c
的{{1}}选项将行的长度设置为要交换的字节数。xxd
- 标签“a”
:a
- 附加下一行。N
- 删除嵌入式换行符s/\n//
- 如果它是最后一行输入:
\${
- 将最后s/\(.*\)\(.\{$hd\}\)\$/\2\1/
个字节交换到开头$hd
- 将保留空间中的第一个G
字节附加到末尾。由于它是最后一行,因此脚本结束。$n
- 结束如果}
- 分支标记为“a”。此外,ba
可以对数据进行一些操作。