web-dev-qa-db-ja.com

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

OverTheWireバンディットチャレンジのレベル5 を行うための効率的な方法を見つけようとしています。

とにかく、私にはたくさんのファイルがあり、次の基準を尊重するファイルは1つだけです。

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

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

find . -size 1033c ! -executable

ただし、人間が読み取れないファイルを除外する方法はわかりません。その課題で見つけたソリューションは-readableテストパラメータですが、これは機能しないと思います。 -readableはファイルのアクセス許可のみを確認し、その内容は確認しませんが、チャレンジの説明ではASCIIファイルなどを要求します。

15
J.Doe

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

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

ただし、問題は思ったほど単純ではありません。 「人間が読める」はひどくあいまいな用語です。おそらく、あなたはテキストを意味します。わかりましたが、どのようなテキストですか?ラテン文字ASCIIのみ?完全なUnicode?たとえば、次の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を使用すると、greptextがスタンドアロンWordとして検出された行のみを印刷します。そのすべきはあなたが望むものにかなり近いですが、説明に文字列textが含まれている可能性のある他のファイルタイプがないことは保証できません。

17
terdon

-execは主に、見つかったファイルを処理するために使用され、テストとしても機能します。したがって、他の基準に追加することができます。

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

パターンが見つからなかった場合、grepはゼロ以外を返し、sh -c "COMMAND"は、評価の結果を返します(有効な場合)。したがって、これはfile <filename>textで終わるものを吐き出します。たとえば、 「UTF-8 Unicodeテキスト」または「ASCIIテキスト」。ただし、「非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
4
Zeta
find . -size 1033c ! -executable -exec file {} +
2
user305801

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

find inhere -size 1033c

それはあなたにパスワードを含む唯一のファイルを与えます。

1
BugHunterUK

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

$ 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>
1
t0lkim
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:~$ 
0
user234732

あなたはこれを試すことができます

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

チャレンジではgrepは許可されていません。パスワードファイルは「ASCIIテキスト、非常に長い行」として報告されます

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

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

0
Fengbo Wu
find . -type f -size 1033c ! -executable | xargs file | grep text

ワンライナーのファン

0
Dark Knight

上記のほとんどで、findとgrepを使用してこのバンディットレベルのパスワードを検索するより長い方法が、最もわかりやすいコマンドだと思います。

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

しかし、「file」コマンドをさらに使用した後、ディレクトリ全体のファイルタイプをチェックすることにより、この方法で人間が読めるファイル(このレベルでは別名ASCII))を見つけるのが非常に簡単であることに気付きました。inhereディレクトリ「-filexx」という名前のファイルを保持するか、file ./*を使用してinhereディレクトリ全体をすばやく確認します

これが私のアプローチでした。

bandit4@bandit:~/inhere$ file ./*
./-file00: data
./-file01: data
./-file02: data
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: data

bandit4@bandit:~/inhere$ cat ./-file07
koReBOKuIDDepwhWk7jZC0RTdopnAYKh
0
Tanner Dolby
find  -type f ! -executable -size 1033c

演習からファイルを取得します

0
coolhand

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

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

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

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

これは、file- partがどのように機能するかを簡単に示したものです。

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