2

这是我构建的脚本

  • 它根据作为参数提供的扩展名获取文件列表。

  • 然后它会删除这些文件中模式 00000000: 之前的所有内容。

  • 模式 00000000: 前面是 string <pre>,然后删除这五个前字符。
  • 然后脚本删除文件的最后三行
  • 该脚本仅输出文件的 hexdump 数据。
  • 脚本运行 xxd 将 hexdump 转换为 file.jpg
    如果 [[ $# -eq 0 ]] ; 然后
        echo '运行脚本为 ./hexconv ext'
        出口 0
    菲

    用于 *.$1 中的文件
    做
        文件名=$(基本名称 $file)
        扩展="${文件名##*.}"
        文件名="${文件名%.*}"

        sed -n '/00000000:/,$p' $file | sed '1s/^.....//' | 头-n -3 | awk '{打印 $2""$3""$4""$5""$6""$7""$8""$9""$10""$11""$12""$13""$14""$15""$16""$17 }' | xxd -p -r > $文件名.jpg
    完毕

它也可以按我的意愿工作,但我怀疑有一些东西可以改进它,但是唉,我是使用 awk 和 sed 的新手。

文件摘录

<th>response-head:</th>
<td>HTTP/1.1 200 OK
Date: Sun, 15 Dec 2013 04:27:04 GMT
Server: PWS/8.0.18
X-Px: ms h0-s34.p6-lhr ( h0-s35.p6-lhr), ht-d h0-s35.p6-lhr.cdngp.net
Etag: &quot;4556354-9fbf8-4e40387aadfc0&quot;
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0
Accept-Ranges: bytes
Content-Length: 654328
Content-Type: image/jpeg
Last-Modified: Thu, 15 Aug 2013 21:55:19 GMT
Pragma: no-cache
</td>
  </tr>
</table>
<hr/>
<pre>00000000:  ff  d8  ff  e0  00  10  4a  46  49  46  00  01  01  01  00  48  ......JFIF.....H
00000010:  00  48  00  00  ff  e1  00  18  45  78  69  66  00  00  49  49  .H......Exif..II
00000020:  2a  00  08  00  00  00  00  00  00  00  00  00  00  00  ff  ed  *...............
00000030:  00  48  50  68  74  73  68  70  20  33  2e  30  00  .HPhotoshop 3.0.
00000040:  38  42  49  4d  04  04  00  00  00  00  00  1c  01  5a  00  8BIM..........Z.
00000050:  03  1b  25  47  1c  02  00  00  02  00  02  00  38  42  49  4d  ..%G........8BIM
00000060:  04  25  00  00  00  00  00  10  fc  e1  89  c8  b7  c9  78  .%.............x
00000070:    34  62  34  07  58  77  eb  ff  e1  03  a5  68  74  74  70  /4b4.Xw.....http
00000080:  3a    6e  73  2e  61  64  62  65  2e  63  6d  ://ns.adobe.com/
00000090:  78  61  70  31  2e  30  00  3c  78  70  61  63  6b  xap/1.0/.&lt;?xpack
000000a0:  65  74  20  62  65  67  69  6e  3d  22  ef  bb  bf  22  20  69  et begin="..." i
000000b0:  64  3d  22  57  35  4d  30  4d  70  43  65  68  69  48  7a  72  d="W5M0MpCehiHzr
000000c0:  65  53  7a  4e  54  63  7a  6b  63  39  64  22  3e  20  3c  eSzNTczkc9d"?&gt; &lt;
000000d0:  78  3a  78  6d  70  6d  65  74  61  20  78  6d  6c  6e  73  3a  x:xmpmeta xmlns:
000000e0:  78  3d  22  61  64  62  65  3a  6e  73  3a  6d  65  74  61  x="adobe:ns:meta
000000f0:    22  20  78  3a  78  6d  70  74  6b  3d  22  41  64  62  /" x:xmptk="Adob
00000100:  65  20  58  4d  50  20  43  72  65  20  35  2e  30  2d  63  e XMP Core 5.0-c
00000110:  30  36  31  20  36  34  2e  31  34  30  39  34  39  2c  20  32  061 64.140949, 2
00000120:  30  31  30  31  32  30  37  2d  31  30  3a  35  37  3a  010/12/07-10:57:

4

2 回答 2

1

尽管@CodeGnome是正确的,而且这可能属于Code Review SE,但无论如何你都可以去:

  1. 将多个sed命令合并为一个命令效率更高,例如:

    sed -n -e 's/^<pre>//' -e '/00000000:/,$p'
    

    我决定收回这部分,因为我不确定它是否更好或更清晰。你的版本很好,除了s/^<pre>//s/^.....//.

  2. exit 1在检查参数数量以发出错误信号时使用

  3. 有什么for file in *.?迭代所有以点结尾的文件?错字?

  4. 除非您 100% 确定文件名永远不会包含空格,否则您应该引用它们,但不要在不需要的地方引用,例如:

    filename=$(basename "$file")  # need to quote
    extension=${filename##*.}     # no need, 
    filename=${filename%.*}       # no need
    sed ... "$file"               # need to quote
    ... | xxd > "$filename".jpg   # need to quote
    
  5. 作为循环,最后一个awk可能更短且更不容易出错:

    ... | awk '{printf $2; for (i=3; i<=17; ++i) printf " " $i; print ""}'
    

看来你想学。您可能也对这个其他答案感兴趣:编写健壮的 shell 脚本的规则是什么?

于 2013-12-15T05:48:42.673 回答
0

错误消息应发送到 stderr,不应硬编码脚本名称以防您稍后重命名它,并且应以非零值退出。

if (( ! $# )); then
  echo >&2 "Run script as '$0' \$extension"
  exit 1
fi

如果您要将 与 放在then同一行if,那么您也应该将 与do放在同一行for,以保持一致性:

for file in *.$1; do

使用file全名和filename基本名会混淆变量名的选择。我会使用basename变量来匹配操作。你需要引用参数扩展:

    basename=$(basename "$file")

但是您不需要引用作业的右侧:

    extension=${basename##*.}

不带扩展名的文件名部分有时称为root(在 vi 和 csh -:修饰符中,您可以:r使用 .

    root=${basename%.*}

至于实际的管道,我会将其重新排序以将 放在head之前awk,因为sedhead都是关于要打印的行,并且应该在awk修改那些选定的行之前组合在一起。我也会使用一个循环并printf使其awk更加实用:

    sed -n '/0\{8\}:/,$p' "$file" | 
      head -n -3 | 
      awk '{ printf "%s", $2; for (f=3;f<=17;++f) { printf " %s", $f }; print "" }' | 
      xxd -p -r > "$root.jpg"
done
于 2017-01-13T16:16:28.247 回答