ファイル拡張子のないデータファイルを見つけたという課題を解決しました。file
それは、コマンド・ショーdata file (application/octet-stream)
。hd
コマンドが表示さGNPを。最後の行に。したがって、このファイルを元に戻すと、.PNG形式のファイルが表示され、どこでも検索しましたが、バイナリファイルの内容を元に戻す方法を説明する解決策が見つかりませんでした。
ファイル拡張子のないデータファイルを見つけたという課題を解決しました。file
それは、コマンド・ショーdata file (application/octet-stream)
。hd
コマンドが表示さGNPを。最後の行に。したがって、このファイルを元に戻すと、.PNG形式のファイルが表示され、どこでも検索しましたが、バイナリファイルの内容を元に戻す方法を説明する解決策が見つかりませんでした。
回答:
付xxd
(からvim
)とtac
(GNUのcoreutilsのから、またtail -r
いくつかのシステムで):
< file.gnp xxd -p -c1 | tac | xxd -p -r > file.png
でzsh
(あなたが考慮したい場合を除き、内部バイナリデータ(に対処することができる唯一のシェルは、ksh93のbase64でエンコードアプローチを)):
zmodload zsh/mapfile
(LC_ALL=C; printf %s ${(s::Oa)mapfile[file.gnp]} > file.png)
LC_ALL=C
:文字はバイトです$mapfile[file.gnp]
:file.gnp
ファイルの内容s::
:文字列をバイト構成要素に分割しますOa
:逆O
にRDER a
rray添字その配列zsh
バイナリデータを処理できるシェルはこれだけではありません。
以下は、を使用してバイナリファイルを反転する1つの方法ですksh93
。わかりやすくするために、コードを「緩い」ままにしました。
#!/bin/ksh93
typeset -b byte
redirect 3< image.gpj || exit 1
eof=$(3<#((EOF)))
read -r -u 3 -N 1 byte
printf "%B" byte > image.jpg
3<#((CUR - 1))
while (( $(3<#) > 0 ))
do
read -r -u 3 -N 1 byte
printf "%B" byte >> image.jpg
3<#((CUR - 2))
done
read -r -u 3 -N 1 byte
printf "%B" byte >> image.jpg
redirect 3<&- || echo 'cannot close FD 3'
exit 0
read
上記の最初のコードは、ファイルの最後で行われるため、何も読み取らないことに注意してください。
strace
し、ksh93
それがファイル内の場所ですべてを追求し、一度に大量に読み込むところ、非常に不気味に動作しているようです。たぶんバリアントgithub.com/att/ast/issues/15
strace
スクリプトを試して、私の意味を確認してください。ksh93
何千回もファイルを読み取ります。たとえば、最初のバイトを読み取る前に、ファイルの終わりから64KiBをシークし、64KiBを読み取ってから、最後のバイトの前をシークして1バイトを読み取り、バイトごとに同様の処理を行います。これらのbase64エンコードされた文字列で実行できることは制限されているため、一度に複数のバイトを読み取る場合、その個々のバイトを抽出することはより困難になります。
perlの場合:
perl -0777pe '$_=reverse $_' [input_file]
性能テスト:
dd if=/dev/urandom of=/tmp/a bs=1M count=1
LC_ALL=C tac -rs $'.\\|\n' /tmp/a > /tmp/r
time perl -0777pe '$_=reverse $_' /tmp/a | diff -q - /tmp/r
time xxd -p -c1 /tmp/a | tac | xxd -p -r | diff -q - /tmp/r
time perl -0777 -F -ape '$_=reverse@F' /tmp/a | diff -q - /tmp/r
time LC_ALL=C tac -rs $'.\\|\n' /tmp/a | diff -q - /tmp/r
結果:
perl -0777 -F
最も遅いです。xxd
最も遅いです。注:diff
出力は同じであるため、実行時間はすべてのソリューションで同じでなければなりません。
perl
。当時reverse
は文字列を逆にすることもできなかったので、分割を行うことはあまり意味がなく、バージョンははるかに優れています。
私は次を試しました:
tac -rs '.' input.gnp > output.png
アイデアは、セパレータとして任意の文字を使用して「tac」を強制することです。私はそれをバイナリファイルで試してみましたが、動作するように見えましたが、確認をお願いします。
主な利点は、ファイルをメモリにロードしないことです。
tac
入力に改行文字が含まれている場合、私(ここではGNU 8.28)では機能しません。printf '1\n2' | tac -rs . | od -vAn -tc
の\n 2 1
代わりに出力します2 \n 1
。また、マルチバイト文字が必要LC_ALL=C
または.
一致する可能性があります。
LC_ALL=C tac -rs $'.\\|\n'
でも動作するようです。