Точно подсчитать, сколько файл действительно занимает на диске, нетривиально, поскольку подробный ответ сложнее, чем просто округлить размер файла до следующего диска блокировать.
А как насчет:
Если вы сложите все это, задача станет почти невозможной без надлежащего внутреннего знания того, как все работает на самом деле (так что определенно не простой стат в файле).
Системные инструменты
Однако существует множество системных инструментов, предназначенных для этого или с опциями «занятых блоков». Вот 2 наиболее часто используемых:
du
От man du
(из FreeBSD, как более подробный):
ОПИСАНИЕ
Утилита du отображает использование блока файловой системы для каждого аргумента файла
и для каждого каталога в файловой иерархии с корнем в каждом аргументе каталога
. Если файл не указан, отображается использование блоков иерархии
в текущем каталоге.
ls -s
From man ls
:
-s, --size
распечатать выделенный размер каждого файла в блоках
(кажется, ls
"блоки" на самом деле устарели Блоки по 1024 байта, а не блоки реального диска)
Пример :
$ dumpe2fs /dev/mapper/vg_centurion-lv_root |head -20 |grep ^Block
dumpe2fs 1.41.12 (17-May-2010)
Block count: 13107200
Block size: 4096
Итак, наша корневая файловая система имеет 4k блоков.
$ ls -l
total 88
-rw-------. 1 root root 2510 Mar 20 18:00 anaconda-ks.cfg
-rw-r--r--. 1 root root 67834 Mar 20 17:59 install.log
-rw-r--r--. 1 root root 12006 Mar 20 17:57 install.log.syslog
С du:
$ du -h anaconda-ks.cfg
4.0K anaconda-ks.cfg
И ls:
$ ls -ls
total 88
4 -rw-------. 1 root root 2510 Mar 20 18:00 anaconda-ks.cfg
72 -rw-r--r--. 1 root root 67834 Mar 20 17:59 install.log
12 -rw-r--r--. 1 root root 12006 Mar 20 17:57 install.log.syslog
Сawk
:
$ awk -v FS="\t" -v OFS="\t" 'NR==FNR {trans[$2"|"$3]++; next;} FNR==1 {print} FNR>1 {if(!trans[$2"|"$3]) print}' file2 file1
file2
, и значения столбцов 2 и 3 используются для сохранения их в качестве ключа в списке. file1
, печатается строка заголовка. Для каждой следующей строки мы проверяем, существует ли ключ со значениями столбцов 2 и 3 в нашем списке, который мы создали ранее. Если нет, мы распечатываем строку. Способ сравнения файлов четко не объяснен/не определен.
Впрочем, это не помешало мне попытаться прочитать ваши мысли...
Насколько я понимаю, файл 2 является своего рода файлом базы данных или ссылкой. Файл 1 предположительно содержит новые данные.
"Сравнение" как я понял :если значение столбца 2 или 3 файла 1 уже найдено в файле 2 (т.е. ссылка ), то не печатать/включать его. В противном случае распечатайте/включите его.
Хорошей новостью является то, что он действительно не требует сортировки... как вы и просили....
Ниже приведен сценарий с двумя параметрами. :Первый — это новый файл данных (файл 1 в вашем примере ). Второй файл базы данных (файл 2 в вашем примере ).
#!/bin/bash
new_file=$1
db_file=$2
# Just checking the last parameter
if [ "x" = "x$db_file" ]; then
echo >&2 "[ERROR] This scripts expect 2 file path as parameter."
exit 1
fi
if [ ! -f $new_file ]; then
echo >&2 "[ERROR] First parameter file doesn't exist."
exit 2
fi
if [ ! -f $db_file ]; then
echo >&2 "[ERROR] First parameter file doesn't exist."
exit 3
fi
declare -A data_base
# Open both files and assign to file descriptor 10 and 11
exec 10< $new_file
exec 11< $db_file
# Step 1
# Building map of base data first (for the comparison to happen in next step)
first_line=1
while [ /bin/true ];
do
read -u 11 db_file_col1 db_file_col2 db_file_col3 db_file_rest || {
break;
}
# Skipping the header so that it will appear in the diff as shown in the example
if [ $first_line -ne 0 ]; then
first_line=0
continue
fi
# Creating map from Col 2 and Col 3 (keys) to the whole line (value)
data_base[$db_file_col2]="$db_file_col1 $db_file_col2 $db_file_col3 $db_file_rest"
data_base[$db_file_col3]="$db_file_col1 $db_file_col2 $db_file_col3 $db_file_rest"
done
# Step 2
# Actual comparison...
while [ /bin/true ];
do
read -u 10 new_file_col1 new_file_col2 new_file_col3 new_file_rest || {
break;
}
if [ -z "${data_base[$new_file_col2]}" ] && [ -z "${data_base[$new_file_col3]}" ]; then
echo "$new_file_col1 $new_file_col2 $new_file_col3 $new_file_rest"
fi
done
Если вы сохраните скрипт в файл с именем process.sh, например (, а затем выполните команду chmod 755 process.sh, чтобы сделать его исполняемым ), то выполнение:
./process.sh file1 file2
в то время как привести к вашему точному ожидаемому выходу/результату.
ПРИМЕЧАНИЕ. :Этот сценарий удерживает в памяти как минимум вдвое больше содержимого файла 2. Убедитесь, что у вас достаточно памяти....