【问题标题】:Unix -Delete even bytes from a fileUnix - 从文件中删除偶数字节
【发布时间】:2020-04-28 11:53:33
【问题描述】:

我想从命令行中给出的文件中查找并删除所有偶数字节。这种情况有什么命令吗?

【问题讨论】:

  • 您是指文件的第 2、4、6 等字节,还是那些具有偶数值的字节?
  • 您的意思是要删除值为24 等的字节,无论它们出现在文件中的什么地方,b) 您要删除第二个、第四个、第六个字节,因此文件大小减半了吗?
  • 我要删除文件的第 2、4、6 等字节。

标签: linux shell file unix


【解决方案1】:

我认为这可以满足您的需求。它将文件转储为连续的普通十六进制,然后读取两个字节,将它们保存以供以后使用,然后再保存两个字节。然后它输出它保存的字节并将整个字节传回xxd“reconstruct”

xxd -p INPUT | sed -E 's/(..)../\1/g' | xxd -r -p > OUTPUT

所以,如果我像这样转储 PNG 图像:

xxd image.png 
00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR
00000010: 0000 0064 0000 0064 0203 0000 000d 8c7d  ...d...d.......}
00000020: c700 0000 0467 414d 4100 00b1 8f0b fc61  .....gAMA......a
00000030: 0500 0000 2063 4852 4d00 007a 2600 0080  .... cHRM..z&...
00000040: 8400 00fa 0000 0080 e800 0075 3000 00ea  ...........u0...
00000050: 6000 003a 9800 0017 709c ba51 3c00 0000  `..:....p..Q<...
00000060: 0950 4c54 4500 0000 ff00 00ff ffff 6719  .PLTE.........g.
00000070: 641e 0000 0001 624b 4744 0266 0b7c 6400  d.....bKGD.f.|d.
00000080: 0000 0774 494d 4507 e404 1c0a 0820 506e  ...tIME...... Pn
00000090: 92c5 0000 0025 4944 4154 48c7 6360 1805  .....%IDATH.c`..
000000a0: a300 0c58 4361 2064 5466 5466 5466 5466  ...XCa dTfTfTfTf
000000b0: 5466 5406 8fcc 2818 3100 00e8 0fcb 7f57  TfT...(.1......W
000000c0: afef dd00 0000 2574 4558 7464 6174 653a  ......%tEXtdate:
000000d0: 6372 6561 7465 0032 3032 302d 3034 2d32  create.2020-04-2
000000e0: 3854 3130 3a30 383a 3332 2b30 303a 3030  8T10:08:32+00:00
000000f0: d513 d3d0 0000 0025 7445 5874 6461 7465  .......%tEXtdate
00000100: 3a6d 6f64 6966 7900 3230 3230 2d30 342d  :modify.2020-04-
00000110: 3238 5431 303a 3038 3a33 322b 3030 3a30  28T10:08:32+00:0
00000120: 30a4 4e6b 6c00 0000 0049 454e 44ae 4260  0.Nkl....IEND.B`
00000130: 82 

然后将其通过我的过滤器并再次显示:

xxd -p image.png | sed -E 's/(..)../\1/g' | xxd -r -pp | xxd 
00000000: 894e 0d1a 0000 4944 0000 0000 0200 008c  .N....ID........
00000010: c700 0441 4100 8ffc 0500 2048 4d00 2600  ...AA..... HM.&.
00000020: 8400 0000 e800 3000 6000 9800 70ba 3c00  ......0.`...p.<.
00000030: 094c 4500 ff00 ff67 6400 0062 4702 0b64  .LE....gd..bG..d
00000040: 0007 4945 e41c 0850 9200 0049 4148 6318  ..IE...P...IAHc.
00000050: a30c 4320 5454 5454 5454 8f28 3100 0f7f  ..C TTTTTT.(1...
00000060: afdd 0025 4574 6165 6365 7400 3030 302d  ...%Etaecet.000-
00000070: 3831 3a38 332b 3030 d5d3 0000 7458 6474  81:83+00....tXdt
00000080: 3a6f 6979 3232 2d34 3254 3030 3a32 303a  :oiy22-42T00:20:
00000090: 304e 6c00 0045 4442 82                   0Nl..EDB.

【讨论】:

    【解决方案2】:

    或者在 Perl 中

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    open my $ifh, '<', $ARGV[0] or die "Need an input filename";
    binmode $ifh;
    open my $ofh, '>', $ARGV[1] or die "Need an output filename";
    binmode $ofh;
    
    my $x;
    while (read $ifh,$x,2) {
        my $num =  pack 'C',ord($x);  # or ord(substr $x,1) for odd bytes 
        print $ofh $num;
    }
    

    【讨论】:

    • print $ofh substr($x, 0, 1); 在循环内也可以工作。
    • 是的。这个包可能是矫枉过正
    【解决方案3】:

    我不确定是否有这样的 shell/bash 内置命令。似乎您需要为此编写自己的 bash 脚本。

    【讨论】:

    • @Adam 这不是解决方案,更多的是评论。
    猜你喜欢
    • 2016-10-17
    • 2015-10-29
    • 2014-02-14
    • 1970-01-01
    • 2016-10-09
    • 1970-01-01
    • 2012-01-31
    • 2017-01-25
    • 2017-11-25
    相关资源
    最近更新 更多