
Я пытаюсь найти эффективный способ сделать это.уровень 5 бандитского испытания OverTheWire.
Так или иначе, у меня есть куча файлов, и только один из них соответствует следующим критериям:
- Человек читаемый
- Размер 1033 байта
- Неисполняемый
Прямо сейчас я используюfind
команда. Мне удалось найти файлы, соответствующие двум последним критериям:
find . -size 1033c ! -executable
Однако я не знаю, как исключить нечитаемые человеком файлы. Решения, которые я нашел для этой проблемы, используют -readable
параметр test, но я не думаю, что это работает. -readable
смотрит только на разрешения файлов, а не на их содержимое, в то время как описание проблемы запрашивает файл ASCII или что-то в этом роде.
решение1
Да, вы можете использовать find
для поиска неисполняемых файлов нужного размера, а затем использовать file
для проверки на ASCII. Что-то вроде:
find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII
Однако вопрос не так прост, как кажется. «Человекочитаемый» — ужасно расплывчатый термин. Вероятно, вы имеете в виду текст. Хорошо, но какой текст? Только латинские символы ASCII? Полный Unicode? Например, рассмотрим эти три файла:
$ 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
.
решение2
Хотя -exec
в основном используется для того, чтобы что-то сделать с найденными файлами, он также может выступать в качестве теста. Поэтому мы можем добавить его к вашим другим критериям:
find . \
-size 1033c \
-not -executable \
-exec sh -c 'file {} | grep "text$"' \;
Помните, grep
возвращает ненулевое значение, если шаблон не найден, и sh -c "COMMAND"
возвращает результат оценки (если он действителен). Таким образом, это выведет только те файлы, где file <filename>
выводится что-то, что заканчивается на text
, например, "UTF-8 Unicode text` или "ASCII text", но не "Non-ISO extended-ASCII text, with escape-последовательности".
В одной строке это даже короче, чем если бы мы перечислили 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
Имеется только 1 файл 1033
размером байт.
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 {} +