
私は効率的な方法を見つけようとしていますOverTheWire バンディットチャレンジのレベル 5。
とにかく、たくさんのファイルがあり、次の基準を満たすのは 1 つだけです。
- 人間が読める
- サイズは1033バイト
- 実行不可
今、私はfind
コマンド。最後の 2 つの条件に一致するファイルを見つけることができます。
find . -size 1033c ! -executable
しかし、人間が判読できないファイルを除外する方法がわかりません。そのチャレンジに対して私が見つけた解決策は、-readable
テスト パラメータを使用するものでしたが、これは機能しないと思います。-readable
チャレンジの説明では、ASCII ファイルなどが要求されていますが、ファイルの権限のみを参照し、その内容は参照しません。
答え1
はい、 を使用して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
したがって、上記のコマンドは、(この例では、ファイルに 1033 文字が含まれていると仮定します)find
のみを検索します。を展開して、文字列を検索できます。file1
find
text
find . -type f -size 1033c ! -executable -exec file {} + | grep -w text
を使用すると-w
、が単独の単語として見つかるgrep
行のみを出力します。text
すべき希望するものにかなり近いと思いますが、説明に文字列が含まれる可能性のある他のファイル タイプが存在しないという保証はありませんtext
。
答え2
-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 テキスト" は印刷しません。
1 行にすると、 を超えるよりも短くなります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
答え3
1033
バイトサイズのファイルは 1 つだけです。
bandit5@bandit:~$ find -size 1033c
./inhere/maybehere07/.file2
bandit5@bandit:~$
なぜ1033c
そうなのか1033
?man
ページを確認してください
-size n[cwbkMG] File uses n units of space, rounding up. The following suffixes can be used: `b' for 512-byte blocks (this is the default if no suffix is used) `c' for bytes `w' for two-byte words `k' for Kilobytes (units of 1024 bytes) `M' for Megabytes (units of 1048576 bytes) `G' for Gigabytes (units of 1073741824 bytes)
ls -l
コマンドで確認するfile
と、すべての答えが得られます。
bandit5@bandit:~$ ls -l ./inhere/maybehere07/.file2
-rw-r----- 1 root bandit5 1033 May 7 20:15 ./inhere/maybehere07/.file2
bandit5@bandit:~$
bandit5@bandit:~$ file ./inhere/maybehere07/.file2
./inhere/maybehere07/.file2: ASCII text, with very long lines
bandit5@bandit:~$
- 人間が読める形式(
ASCII text
) - サイズは1033バイト(
ls -l
出力にも) - 実行不可(
-rw-r-----
)
答え4
find . -size 1033c ! -executable -exec file {} +