
Я обнаружил, что для поиска размера файла в байтах я использую «c».
Итак, я могу найти размер файла размером 1000 байт, используя: find . -size 1000c
Но как насчет других размеров, таких как Мб, Гб или даже бит? Какой символ или буквы мне нужно использовать?
решение1
POSIXуказывает только отсутствие суффикса или c
суффикс. Без суффикса значения интерпретируются как блоки по 512 байт; с c
суффиксом значения интерпретируются как количество байт, как вы определили.
Некоторые реализации поддерживают больше суффиксов, напримерГНУfind
поддерживает
b
для блоков по 512 байтc
для байтовw
для 2-байтовых словk
для кибибайтовM
для мебибайтG
для гибибайтов
решение2
find . -size 1000c # files whose size¹ is exactly 1000 bytes (not characters)
find . -size -1000c # strictly less than 1000 bytes (0 - 999)
find . -size +1000c # strictly more than 1000 bytes (1001 - ∞)
Затем, используя sh
синтаксис POSIX, вы можете сделать:
EiB=$((1024*(PiB=1024*(TiB=1024*(GiB=1024*(MiB=1024*(KiB=1024)))))))
EB=$((1000*( PB=1000*( TB=1000*( GB=1000*( MB=1000*( kB=1000)))))))
find . -size "$(( 12 * GiB ))c" # exactly 12GiB (12,884,901,888 bytes)
find . -size "$(( 12 * GB ))c" # exactly 12GB (12,000,000,000 bytes)
find . -size "-$(( 12 * GB ))c" # 0 - 11,999,9999,999 bytes
...
Будьте осторожны, без суффикса c
поведение может оказаться неожиданным:
find . -size 1000 # files whose size, in number of 512-byte units (rounded *up*)
# is 1000. So, that's file whose size in bytes ranges from
# 1000*512-511 (999*512+1) to 512*1000
find . -size -1000 # files whose size is 999*512 bytes or less
find . -size +1000 # files whose size is 1000*512+1 bytes or more
На этом спецификация POSIX утилиты заканчивается find
.
Теперь различные find
реализации поддерживают дополнительные суффиксы, но будьте осторожны: одни и те же суффиксы могут интерпретироваться по-разному в разных реализациях.
Какотмечено @StephenKitt,ГНУfind
поддерживает cwbkMG
байт, слово, 512-байтовый блок, кибибайт, мебибайт, гибибайт, но ведет себя так, как find
требует POSIX find . -size -12G
, например, это не то же самое, что и наш find . -size "-$((12 * GiB))c"
вышеприведенный пример, поскольку это файлы, размер которых в гибибайтах (округленный) строго меньше 12, то есть файлы размером 11 ГиБ или меньше.
Например, find . -size -1G
находит только пустые файлы (файлы размером 0). Файл размером в один байт считается файлом размером 1 ГиБ, поскольку размеры округляются до следующего ГиБ.
busyboxfind
поддерживает cwbk
суффиксы, но интерпретирует их иначе, чем GNU find
. Это такжев настоящее время несовместим с POSIX для обработки размеров без суффиксов.
Для busybox find
,find . -size -12G
являетсякак и find . -size "-$(( 12 * GiB ))c"
, и find . -size -1
предназначен для размеров от 0 до 511, а не только 0.
Ящик для игрушекfind
(например, как на Android) ведет себя find
в этом отношении как busybox (и такженесовместимо с POSIX). Другое отличие заключается в том, что суффиксы здесь нечувствительны к регистру, а TPE
для тебибайта, пебибайта и эксбибайта также поддерживаются, а d
(десятичный) дополнительный суффикс может использоваться для указания того, что единицы являются степенями 1000, а не 1024. Например, -size 1kd
находит файлы размером ровно 1000 байт (1 килобайт) вместо 1024 байт (1 кибибайт) для -size 1k
.
В toybox find
обработка суффикса выполняется как часть его atolx()
функции, которая используется не только для find
. Однако следует отметить, что поскольку поддерживает 0xffff
шестнадцатеричные числа, возникает конфликт для cbedCBED
, которые также являются шестнадцатеричными цифрами. -size -0x2c
не для менее 0x2 байт, а для менее 0x2c (44) 512-байтовых единиц. И -size 010c
рассматривается как -size 8c
(восьмеричное), еще одно несоответствие POSIX.
FreeBSD/DragonFly BSD find
поддержка ckMGTP
(не bwE
), но хотя он ведет себя так, как требует POSIX без суффикса, find
при наличии суффикса он ведет себя как busybox/toybox, а не как GNU².
sfind
или find
встроенная оболочка bosh ведет себя как FreeBSD, за исключением того, что суффиксы нечувствительны к регистру и bwE
поддерживаются восьмеричные/десятичные числа и некоторыеарифметические выражения произведения(например 6x12x8k
, ) принимаются.
Насколько я могу судить, всеOpenBSD,NetBSD,Иллюмос,Солярис,ЭКС,HP/UXподдержка no-suffix только для 512-байтовых единиц или c
для байтов, как того требует POSIX.
Сводная таблица:
Традиционный/POSIX | ГНУ | FreeBSD | sfind | busybox | Ящик для игрушек | |
---|---|---|---|---|---|---|
суффиксы | с | cwbkMG | ckMGTP | cwbkmgtpeCWBKMGTPE | cwbk | cwbkmgtpeCWBKMGTPE (+d) |
числовой формат | десятичная дробь | десятичная дробь | десятичная дробь | десятичный/восьмеричный/шестнадцатеричный/выражение | десятичная дробь | десятичный/восьмеричный/шестнадцатеричный |
-size $n |
($n-1)*512+1 .. $n*512 | ($n-1)*512+1 .. $n*512 | ($n-1)*512+1 .. $n*512 | ($n-1)*512+1 .. $n*512 | $n*512 | $n*512 |
-size -$n |
0 .. ($n-1)*512 | 0 .. ($n-1)*512 | 0 .. ($n-1)*512 | 0 .. ($n-1)*512 | 0 .. $n*512-1 | 0 .. $n*512-1 |
-size +$n |
($n*512)+1 .. ∞ | ($n*512)+1 .. ∞ | ($n*512)+1 .. ∞ | ($n*512)+1 .. ∞ | ($n*512)+1 .. ∞ | ($n*512)+1 .. ∞ |
-size ${n}c |
$н | $н | $н | $н | $н | $н |
-size -${n}c |
0 .. $n-1 | 0 .. $n-1 | 0 .. $n-1 | 0 .. $n-1 | 0 .. $n-1 | 0 .. $n-1 |
-size +${n}c |
$n+1 .. ∞ | $n+1 .. ∞ | $n+1 .. ∞ | $n+1 .. ∞ | $n+1 .. ∞ | $n+1 .. ∞ |
-size $n$unit |
Н/Д | ($n-1)*$единица+1 .. $n*$единица | $n*$единица | $n*$единица | $n*$единица | $n*$единица |
-size -$n$unit |
Н/Д | 0 .. ($n-1)*$единица | 0 .. $n*$unit-1 | 0 .. $n*$unit-1 | 0 .. $n*$unit-1 | 0 .. $n*$unit-1 |
-size +$n$unit |
Н/Д | $n*$единица+1 .. ∞ | $n*$единица+1 .. ∞ | $n*$единица+1 .. ∞ | $n*$единица+1 .. ∞ | $n*$единица+1 .. ∞ |
Итак, короче говоря, для переносимости лучше всего использовать суффикс c
, только десятичные числа без начальных нулей и вычислять единицы вручную.
Для полноты картины, L
квалификатор glob zsh
( kmgt
нечувствительный к регистру, но pP
предназначенный для единицы размером 512 байт, а не пебибайт) ведет себя как POSIX/GNU find
( *(LM-12)
например, расширяется до файлов, размер которых находится в диапазоне от 0 до 11 мебибайт).
¹ Это размер, указанный в st_size
атрибуте возвращаемой структуры, lstat()
значение которого для нестандартных файлов может различаться в зависимости от системы.
² В FreeBSD есть такое же различие find
/ sfind
для -Xtime
предикатов, где, например, -mtime +1
совпадения с файлами, которым 2 дня или больше (возраст 86400*2 - ∞), а -mtime +1d
совпадения с файлами, которым больше одного дня (возраст 86400.000000001 - ∞). В GNU find
см. также ! -newermt -1day
(или 1 day ago
или yesterday
).
решение3
В дополнение к тому, что сказал Стивен Китт, будьте осторожны, что gnu findокругляетразмер до указанной детализации перед сравнением!
Если ты это сделаешь
truncate --size=1000 dummy_file_1000
truncate --size=1024 dummy_file_1024
затем
find . -size 1k
find . -size 1024c
волянетдают тот же результат!
Видетькоманда find: -size поведение
Короче говоря, find . -size 1k
будут выведены все файлы с размером ∈ [1,1024], тогда как find . -size 1024c
будут выведены только файлы, фактический размер которых составляет ровно 1024 байта.