人間が読めるファイルを見つける


14

OverTheWire Banditチャレンジのレベル5を実行する効率的な方法を見つけようとしています。

とにかく、私はたくさんのファイルを持っています、そして、以下の基準を尊重するものだけがあります:

  • 人間が読める
  • サイズは1033バイト
  • 非実行可能

現在、このfindコマンドを使用していますが、最後の2つの条件に一致するファイルを見つけることができます。

find . -size 1033c ! -executable

ただし、人間が読み取れないファイルを除外する方法はわかりません。その挑戦のために私が見つけた解決策は-readableテストパラメータを使用しますが、私はこれがうまくいくとは思いません。-readableチャレンジの説明ではASCIIファイルまたはそのようなものを要求しますが、コンテンツではなくファイルの許可のみを調べます。


1
人間が読める形式をどのように定義しますか?バイナリではない?
テルドン

1
ファイルコマンドはあなたの友人です:)
ロミオニノフ

重複する可能性があります:stackoverflow.com/questions/14505218/…–
zuazo

2
人間は地球上で最も知られている種の1つです。また、コンピューターに精通していることが知られている唯一のものです。タイプを見つけて、暗号化されたキーの暗号化キーを取得できれば、ほとんどのファイルを読み取ることができます。
ステファンシャゼル16

1
スポイラー警告!!
ダンボルサー

回答:


16

はい、find適切なサイズの非実行可能ファイルを検索してfileから、ASCIIを確認するために使用できます。何かのようなもの:

find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII

しかし、質問は思ったほど簡単ではありません。「人間が読める」というのは恐ろしく曖昧な用語です。おそらく、あなたはテキストを意味します。わかりましたが、どのようなテキストですか?ラテン文字ASCIIのみ?完全なユニコード?たとえば、次の3つのファイルについて考えます。

$ cat file1
abcde
$ cat file2
αβγδε
$ cat file3
abcde
αβγδε
$ cat file4
#!/bin/sh
echo foo

これらはすべてテキストであり、人間が読むことができます。それでは、fileそれらが何でできているのか見てみましょう。

$ file *
file1: ASCII text
file2: UTF-8 Unicode text
file3: UTF-8 Unicode text
file4: POSIX shell script, ASCII text executable

したがって、find上記のコマンドは検索のみを行いますfile1(この例のために、これらのファイルには1033文字が含まれていると想像してください)。を展開findして文字列を探すことができますtext

find . -type f -size 1033c ! -executable -exec file {} + | grep -w text

を使用すると-w、スタンドアロンの単語として見つかったgrep行のみが印刷textされます。それあなたが望むものにかなり近いはずですが、説明に文字列が含まれている可能性のある他のファイルタイプがないことを保証することはできませんtext


4

一方では、-exec主に見つけた、それはまた、テストとして作用することができることをファイルで何かをするために使用されます。したがって、他の基準に追加できます。

find . \
  -size 1033c \
  -not -executable \
  -exec sh -c 'file {} | grep "text$"' \;

覚えておいて、grep戻って非ゼロパターンが見つかりませんでした、とsh -c "COMMAND"(限り、それが有効だとして)評価の結果を返します。したがって、これは、「UTF-8 Unicode text」または「ASCII text」などfile <filename>で終わる何かを吐き出すファイルのみを出力しますがtext、「非ISO拡張ASCIIテキスト、エスケープシーケンス」は出力しません。

一行で、それは行き過ぎるよりも短くなりxargsます:

find . -size 1033c -not -executable -exec sh -c 'file {} | grep "text$"' \;

sh -c 'file {} | grep "text$"'カスタムコマンドに置き換えることができることに注意してください。非常に複雑なものを確認する場合は、シェルスクリプトを提供し、代わりにそれを使用することをお勧めします。

find . -size 1033c -not -executable -exec is_human_readable.sh {} \;

長期的には、シェルの履歴よりも保守が簡単です。

#!/bin/sh
file "$@" | grep "text$" > /dev/null

いいね!ただし、一致するtext$と、シェルスクリプトとして認識されるものが除外されることに注意してください。シバンのあるものはすべてスクリプトとして識別され、それらは完全に人間が読むことができます。
テルドン

@terdon trueですが、スクリプトは実行可能です:D。そうは言っても、適切なスクリプトはPDFも認識する必要があります。しかし、一方で、人間が読める画像を含むPDFはありますか?いくつかのテキストのPNGは読み取り可能ですか?多分。完全なテストは挑戦的だと思います。
ゼータ


1

あなただけを使用する必要があります:

find inhere -size 1033c

パスワードを含む唯一のファイルが提供されます。


なぜ+ 1033cはより多くのファイルを返すのですか?それは、以上の記号のようなものですか?
szeitlin

1

ディレクトリの内容に対して次を実行するだけです。

$ file -- *
-file00: data
-file01: data
-file02: data
-file03: data
-file04: data
-file05: data
-file06: data
-file07: ASCII text
-file08: data
-file09: data
$ cat -- \-file07
<output>

0
find . -size 1033c ! -executable|xargs file|grep "ASCII text" |awk -F: '{print $1}'

この組み合わせコマンドを試してください。それは私のステーションで動作します。


0

これを試すことができます

find . -size 1033c ! -executable -exec file {} +

あなたの挑戦は許しません grep。パスワードファイルは「ASCIIテキスト、非常に長い行」として報告されます


0

人間が読めるファイル名を除外するには、[:print:]印刷可能な文字クラス名を使用できます。そのようなクラスの詳細については、のマニュアルを参照してくださいgrep

find . -type f -size 1033c -name "[[:print:]]*" ! -executable

考え直して、「人間が読める」要件は、ファイルの名前ではなくコンテンツを参照する場合があります。つまり、テキストファイルを検索することになります。それはもう少し難しいです。コメントで@D_Byeが示唆したように、fileコマンドを使用してファイルコンテンツタイプを決定する必要があります。しかしfile、パイプの後に実行することはお勧めできません。ファイル名を表示するタスクが複雑になるからです。ここに私が提案するものがあります:

find . -type f -size 1033c ! -executable -exec sh -c 'file -b $0 | grep -q text' {} \; -print

これは、file-partの仕組みを簡単に示したものです。

  • -exec述語の実行sh -c 'file -b $0 | grep -q text' FILENAME各々についてFILENAME満たすすべての以前の条件(種類、サイズ、非実行)。
  • これらのファイルごとに、シェル(sh)がこの短いスクリプト:を実行し、ファイル名file -b $0 | grep -q textに置き換え$0ます。
  • fileプログラムは、各ファイルのコンテンツタイプを決定し、この情報を出力します。この-bオプションは、テストされた各ファイルの名前を出力しません。
  • grepfileプログラムからの出力をフィルタリングし、"text"を含む行を検索します。(fileコマンドの典型的な出力がどのようになるかを自分で確認してください。)
  • ただしgrep-q(quiet)オプションが指定されているため、フィルターされたテキストは出力されません。実行するのは、終了ステータス0(「true」-フィルタリングされたテキストが見つかったことを表す)または1(「error」-テキスト「text」がからの出力に表示されなかったことを意味するfile)に変更するだけです。
  • からのtrue / false終了ステータスgrepはさらにshtoに渡さfindれ、-exec sh -c 'file $0 | grep -q text' {} \;テスト全体の最終結果として機能します。
  • 上記のテストがtrueを返した場合-printコマンドが実行されます(つまり、テストされたファイルの名前が出力されます)。

0
bandit4@bandit:~$ ls
inhere

bandit4@bandit:~$ file inhere/*


inhere/-file00: data
inhere/-file01: data
inhere/-file02: data
inhere/-file03: data
inhere/-file04: data
inhere/-file05: data
inhere/-file06: data
inhere/-file07: ASCII text
inhere/-file08: data
inhere/-file09: data

bandit4@bandit:~$ pwd 

/home/bandit4

bandit4@bandit:~$ cat /home/bandit4/inhere/-file07

koReBOKuIDDepwhWk7jZC0RTdopnAYKh
bandit4@bandit:~$ 

ファイルinhere / *とcat / home / bandit4 / inhere / -file07を使用するだけです



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.