Я пытаюсь проиндексировать свою файловую систему. Что я хочу сделать, это: выполнить команду find
, и для каждой записи сохранить время последнего доступа, время последнего изменения, вычислить хэш и другие операции. Для этого я подумал выполнить следующую команду:
find . -printf 'PATHNAME=%p -- NAME=%f -- SIZE=%s -- LAT=%a -- LCT=%c -- LMT=%t \n' -exec file {} \; -exec md5sum {} \;
Вывод будет выглядеть примерно так:
PATHNAME=./script -- NAME=script -- SIZE=807 -- LAT=Fri Apr 15 16:39:52.0874615579 2016 -- LCT=Tue Apr 12 12:20:57.0767950320 2016 -- LMT=Tue Apr 12 12:20:57.0767950320 2016 <br>
./script: ASCII text <br>
cf1b934c226b194bee96106ea3f019a4 ./script
Теперь я хотел бы взять все эти параметры (например, parse их с awk
) и положить их куда-нибудь (например, в базе данных). Итак, мой вопрос: как я могу каждый раз перенаправлять эти 3 строки в скрипт для разбора? Есть ли лучший способ написать команду?
Я использовал бы что-то вроде этого (без части вставки в базе данных)
while read EMPTY_LINE; do
read FILE_SIZE
read FILE_AT
read FILE_MT
read FILE_CT
read MIME_INFO
read HASH FILE_PATH
echo
echo 'File path: '"$FILE_PATH"
echo 'File size: '"$FILE_SIZE"
echo 'File times (access - modified - changed): '"$FILE_AT - $FILE_MT - $FILE_CT"
echo 'MIME stuff: '"$MIME_INFO"
echo 'Hash: '"$HASH"
done < <(find . -type f -printf '\n' -exec stat --printf '%s\n%X\n%Y\n%Z\n' {} \; -exec file -b {} \; -exec md5sum {} \; )
Хорошо, поэтому что точно происходит здесь, и почему я делал это этот путь?
Сначала команда find . -type f -printf '\n' -exec stat --printf '%s\n%X\n%Y\n%Z\n' {} \; -exec file -b {} \; -exec md5sum {} \;
выполняется.
Давайте сломаем это.
find .
найдите материал в .
(который является текущим каталогом),
-type -f
найдите только файлы
-printf '\n'
распечатайте пустой файл для каждого соответствия файла
-exec stat --printf '%s\n%X\n%Y\n%Z\n' {} \;
выполните команду статистики, печатающую несколько статистических данных файла, которые я указал сам - посмотрите stat --help
для доступной статистики
-exec file -b {} \;
выполните команду файла для определения информации о MIME. -b
удостоверяется, что имя файла не печатается наряду с ним. Мы проигнорировали бы его так или иначе.
-exec md5sum {} \;
выполните команду md5sum для вычисления md5 хеша содержания файла.
Таким образом для настолько хорошего. -exec
аргументы обрабатываются в указанном порядке. Это означает на соответствие файла, мы получим следующие строки как
[FILE SIZE - from stat command]
[FILE LAST ACCESS TIME - from stat command]
[FILE LAST MODIFICATION TIME - from stat command]
[FILE LAST CHANGE TIME - from stat command]
[MIME INFO - from file command]
[HASH - from md5sum command] [FILE PATH - from md5sum command]
Давайте испытаем find
команда, чтобы видеть, производит ли это все, как мы ожидали бы.
[~/somedir]:$ find . -type f -printf '\n' -exec stat --printf '%s\n%X\n%Y\n%Z\n' {} \; -exec file -b {} \; -exec md5sum {} \;
1752
1441609114
1441609114
1441609114
ASCII text
4fb6f64ce9d07be553a81644b17fe69b ./README.md
./tuptime-install.sh
1649
1441609114
1441609114
1441609114
Bourne-Again shell script, ASCII text executable
9ee7ad860bfa049d1d5f589fba218c6a ./tuptime-install.sh
Существует много, который может пойти не так, как надо при парсинге этих вещей. Что происходит, если существует пространство в имени файла? Или некоторый другой странный символ? Или в других параметрах. Для избавлений от этой проблемы и других, я использовал новые строки явно. Таким образом, мы можем считать сплошную линию и обработать ее соответственно. Никакой специальный парсинг не необходим. (за исключением части хеша, но мы доберемся до той части в немного),
Цикл с условием продолжения будет питаться вывод find
команда. Цикл с условием продолжения будет работать, пока существует оставленная строка. Мы читаем пустую строку, с которой начинается каждый матч. Пустая строка не на самом деле действительно необходима, но мы будем использовать ее для содержания ouput в чистоте.
Сценарий симпатичен сам объяснительный. Это читает строки один за другим в переменные в порядке, мы ожидаем, что они будут присутствовать. После этого мы печатаем их.
Путь read
управляйте работами, что, если единственное имя переменной дано, оно считает целую строку в данное имя переменной. Если нескольким переменным дают, строка разделяется с пробелом (по умолчанию) и помещается в данные переменные. Мы только использовали его для md5sum
управляйте, поскольку мы не могли указать опцию, которая избавится от имени файла. Мы, возможно, получили имя файла от find
'или stat
, но потому что md5sum не имеет опции опустить его по причинам эффективности, мы будем использовать тот.
Я также использовал unixtime
вместо человекочитаемого формата для меток времени. Наличие данных в самой необработанной форме, если это возможно, в большинстве случаев предпочтено.
Только вещь, которая осталась бы, будет состоять в том, чтобы поместить данные в базу данных.
File path: ./README.md
File size: 1752
File times (access - modified - changed): 1441609114 - 1441609114 - 1441609114
MIME stuff: ASCII text
Hash: 4fb6f64ce9d07be553a81644b17fe69b
File path: ./tuptime-install.sh
File size: 1649
File times (access - modified - changed): 1441609114 - 1441609114 - 1441609114
MIME stuff: Bourne-Again shell script, ASCII text executable
Hash: 9ee7ad860bfa049d1d5f589fba218c6a