эффективный размер файла перекрестной OS окружает функцию

Вот:

sed -e 's/^\(\s*\)\.\+/\1/;s/\.\+\s*$//' your_file

Это распечатает измененный файл к стандартному выводу. Для записи в другой файл используйте:

sed -e 's/^\(\s*\)\.\+/\1/;s/\.\+\s*$//' your_file >new_file

Для изменения файла на месте использовать

sed -i -e 's/^\(\s*\)\.\+/\1/;s/\.\+\s*$//' your_file

Править

  • Измененный regexes для составления (возможного) продвижения или запаздывающего пробела.
  • Измененный regexes для сохранения ведущего пробела согласно комментарию manatwork.
4
23.08.2014, 01:16
5 ответов

Из источника wc ( coreutils / src / wc.c ) в GNU coreutils (то есть версии для невстроенных Linux и Cygwin):

 When counting only bytes, save some line- and word-counting
 overhead.  If FD is a 'regular' Unix file, using lseek is enough
 to get its 'size' in bytes.

Таким образом, использование wc -c для подсчета байтов будет эффективным.

Вы можете легко протестировать эту оптимизацию на большом файле (т. Е. На том, для чтения которого потребуется некоторое время). wc -c для файла размером 9,9 ГБ заняла 0,015 секунды реального времени для файла, который находится на моем сервере, и я был бы рад, если бы весь файл был передан за это время, но мой гигабитный Ethernet к сожалению, не так быстро (требуется 21 секунда, чтобы скопировать этот файл в / dev / null по сети).

5
27.01.2020, 20:46
[

]Есть время для всего, включая парсинг []ls[]. Нет никакого портативного способа предотвратить []ls[] от искажения имен файлов, но когда вас интересуют только некоторые метаданные об одном файле, это нормально.[

] [
filesize () {
  LC_ALL=C ls -dn -- "$1" | awk 'NR==1 {print $5}'
}
] [

]Это работает на всех системах, совместимых с []POSIX[] с расширением []XSI[]. Он работает с BusyBox, который понимает []-n[], но не []-o[]. Опция []-n[] заставляет пользовательские и групповые столбцы содержать числовые значения (UID и GID), а не имена (которые могут содержать пробелы в некоторых системах, что делает разбор столбцов ненадежным). Я не думаю, что []LC_ALL[] необходима, так как на эту часть вывода не должны влиять локали, но там может быть реализация, которая делает что-то странное, например, печатает размеры согласно []LC_NUMERIC[], и это не повредит. [

] [

]Если вам нужна только переносимость между системами, где можно установить zsh (который поставляется в комплекте с OSX), вы можете использовать zsh's [][]zstat[][]:[

] [
zmodload -F zsh/stat b:zstat
filesize () {
  zstat +size -- $1
}
]
2
27.01.2020, 20:46

я исключаю stat и perl, которые не являются POSIX, поэтому более вероятно, что они отсутствуют, чем ls и awk.

Я тоже исключаю wc, поскольку в то время как реализация GNU wc оптимизирована, когда используется вариант -c, вы не должны полагаться на то, что он будет присутствовать для портативного сценария. Более того, некоторые нестандартные -c могут возвращать количество символов -c, которое не обязательно совпадает с количеством байт -c в зависимости от локали.

В этом случае решение основано только на стандартных утилитах, которые сообщают размер файла в качестве аргумента:

filesize() {
        [ -f "$1" ] && ls -dnL -- "$1" | awk '{print $5;exit}' || { echo 0; return 1; }
}

Остерегайтесь, однако, что сообщенный размер может быть либо больше, либо меньше фактического размера содержимого файла на диске, в зависимости от используемой файловой системы, поддержки разреженных файлов, а также таких опций, как сжатие или дедупликация.

4
27.01.2020, 20:46

Чем проще, тем портативнее может быть perl:

filesize() {
  file="$1"
  if [ -e "$file" ]; then
    size="$(perl -e 'print -s shift' "$file")"
    printf '%s\n' "$size"
    return 0
  else
    printf "0\n"
    return -1
  fi
}
2
27.01.2020, 20:46

Думаю, тебе стоит использовать это. Как я только что узнал, это стандартная утилита POSIX-specified .

du

Опции, указанные в POSIX, включают:

Утилита du должна соответствовать XBD Utility Syntax Guidelines .

Поддерживаются следующие опции:

  • -a. Кроме вывода по умолчанию, сообщите размер каждого файла, не относящегося к директории типа в файловой иерархии, корни которой лежат в указанном файле. Независимо от наличия опции -a, в списке всегда должны быть указаны недиректории, заданные в качестве файловых операндов.
  • -H Если в командной строке указана символическая ссылка, то du считает размер файла или иерархии файлов, на которые ссылается ссылка.
  • -k Запишите размер файлов в единицах измерения 1024 байта, а не в единицах измерения по умолчанию 512 байт.
  • -L Если символическая ссылка указана в командной строке или встречается во время обхода файловой иерархии, то du считает размер файла или файловой иерархии, на которые ссылается ссылка.
  • -s Вместо вывода по умолчанию сообщайте только общую сумму по каждому из указанных файлов.
  • -x При оценке размеров файлов оценивайте только те файлы, которые имеют то же устройство, что и файл, указанный файловым операндом. Указание более чем одной из взаимоисключающих опций -H и -L не считается ошибкой. Последняя указанная опция определяет поведение утилиты.

Проблема заключается в том, что она не сообщает о размере файла, а сообщает на disk-usage . Это разные понятия, и различия зависят от файловой системы. Если вы хотите получить размер файлов для набора файлов, вы можете использовать что-то вроде:

{   echo
    /usr/bin/ls -ndL .//*
} | sed '/\n/P;//D;N
\|//|s|\n|/&/|
$s|$|/|;s| .//|/\
/|;2!P;D'

Это довольно простой бит sed, который поддерживает двухстрочное адресное окно на выходе ls. Он работает, скользя по своему входу - всегда P прокручивая затем D поднимая самую старую из двух строк в своем шаблоне, а затем вытягивая Next input line, чтобы заменить его. По сути, это однострочный взгляд.

У него есть некоторые существенные недостатки в том виде, как они написаны. Например, для собственного удобства я избегал работы с ls -> linkpath и вместо этого использовал опцию -Ls, которая заставляет ls сообщать о цели соединения, а не о самом соединении. Она также предполагает только глобусы текущего каталога. Это зависит от / not происходящего в именах файлов - потому что это разделитель. На самом деле это довольно часто встречается - вы cd попадаете в каталог и cd - отступаете.

Все это может быть обработано, может быть, в несколько строк или больше, но это всего лишь демонстрация.

Ключевой компонент здесь - и причина просмотра - вот этот бит:

\|//|s|\n|/&/|

Когда самая новая линия в пространстве шаблонов содержит строку .// добавьте / к хвосту самой старой линии и вставьте / в голову самой новой. Затем я также заменяю .// на другой \n швеллер и еще два швеллера с линейным разделением.

И вот это:

drwxr-xr-x 1 1000 1000        6 Aug  4 14:40 .//dir*
drwxr-xr-x 1 1000 1000        0 Aug  4 14:40 .//dir1
drwxr-xr-x 1 1000 1000        6 Aug  8 17:34 .//dir2
drwxr-xr-x 1 1000 1000       22 Aug 10 18:12 .//dir3
drwxr-xr-x 1 1000 1000       16 Jul 11 21:59 .//new
-rw-r--r-- 1 1000 1000        8 Aug 20 11:32 .//newfile
-rw-r--r-- 1 1000 1000        0 Jul  6 11:24 .//new
file
-rw-r--r-- 1 1000 1000        0 Jul  6 11:24 .//new
file
link

становится таким:

/drwxr-xr-x 1 1000 1000        6 Aug  4 14:40/
/dir*/
/drwxr-xr-x 1 1000 1000        0 Aug  4 14:40/
/dir1/
/drwxr-xr-x 1 1000 1000        6 Aug  8 17:34/
/dir2/
/drwxr-xr-x 1 1000 1000       22 Aug 10 18:12/
/dir3/
/drwxr-xr-x 1 1000 1000       16 Jul 11 21:59/
/new/
/-rw-r--r-- 1 1000 1000        8 Aug 20 11:32/
/newfile/
/-rw-r--r-- 1 1000 1000        0 Jul  6 11:24/
/new
file/
/-rw-r--r-- 1 1000 1000        0 Jul  6 11:24/
/new
file
link/

Но что это за польза, верно? Ну, это все меняет:

IFS=/; set -f; set $(set +f
{   echo 
/usr/bin/ls -ndL .//*
}| sed '/\n/P;//D;N
\|//|s|\n|/&/|
$s|$|/|;s| .//|/\
/|;2!P;D'
)

unset IFS
while [ -n "$2" ]
do  printf 'Type :\t <%.1s>\tSize :\t %.0s%.0s%.0s<%d>%.0s%.0s%.0s\nFile :\t %s\n' \
        $2 "<$4>"
shift 4; done

OUTPUT

Type :   <d>    Size :   <6>
File :   <dir*>
Type :   <d>    Size :   <0>
File :   <dir1>
Type :   <d>    Size :   <6>
File :   <dir2>
Type :   <d>    Size :   <22>
File :   <dir3>
Type :   <d>    Size :   <16>
File :   <new>
Type :   <->    Size :   <8>
File :   <newfile>
Type :   <->    Size :   <0>
File :   <new
file>
Type :   <->    Size :   <0>
File :   <new
file
link>
2
27.01.2020, 20:46

Теги

Похожие вопросы