ext4
имеет концепцию «зарезервированных блоков», которые могут быть заполнены только процессом, работающим от имени пользователя root. Возможно, вывод из df
учитывает это.
Например, в одной системе df
показывает:
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 30626752 14557916 14490036 51% /
Здесь 30626752 -14557916 -14490036 равно 1578800, что составляет около 5 % от общего количества, по умолчанию зарезервированного блока. Изменение процента зарезервированных блоков на ноль с помощью tune2fs(tune2fs -m 0 /dev/sda1
)изменяет числа, показанные df
:
.
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 30626752 14557924 16052444 48% /
(Цифры по-прежнему не совсем совпадают, имеется 16384 неучтенных блока по 1 КБ, но я предполагаю, что это связано с некоторой внутренней структурой файловой системы, которая по какой-то причине не считается «используемой».)
Вы можете сделать это вawk
:
if($0 ~ /^$/){next};
→ игнорировать, если это пустая строка
if(NR==1){hd=$0;h=1;next}
→ Сохраните заголовок в переменной 'hd' и перейдите к следующей строке для разбора.
f=$3$4$5
→ Сохраните имя файла в 'f' переменной (, поскольку '-' также является разделителем, его значение отделено и доступно i n ${3,4,5} соответственно. Наконец, во время печати мы добавляем «.txt»
awk -F'[|-]' '{
if($0 ~ /^$/){next};
if(NR==1){hd=$0;h=1;dt=$2;next}
f=$3$4$5;sum+=$6;c++;
if ( dval != f ) { h=1;printf "%s|%s|%s|%.2f\n","T",dt,c,v6 >> dval".txt";temp=$6;sum=0;c=0};
if ($0 ~ /^T/ ) { next; }
if ($0 ~ /^R/ ){v6=sum+temp;}
if(h){print hd"\n\n"$0"\n" > f".txt"; h=0;}else{ print $0"\n" >> f".txt";}dval=f;
}' inputFile
Выход:
$ cat 20190305.txt
H|20200425|abcd|sum
R|abc|2019-03-05|10.00
R|abc|2019-03-05|20.00
R|abc|2019-03-05|30.00
T|20200425|3|60.00
$ cat 20190306.txt
H|20200425|abcd|sum
R|abc|2019-03-06|100.00
R|abc|2019-03-06|15.00
R|abc|2019-03-06|10.00
T|20200425|3|125.00
Вы можете попробовать это:
awk -F'|' '
# get the 2nd field of the header
NR == 1 {
a = $2
h = $0
next
}
# get the date formatted
NR == 2 {
d = $3; gsub(/-/,"",d)
print h > d
}
# if the line starts with 'R', sum the column and get the count of them
$1 == "R" {
sum += $4
++c
}
{
print > d
}
# print the final line with variables acquired
END {
OFS = "|"; print "T",a,c,sum".00" > d
}
' file
Выход:
$ cat 20190305.txt
H|20200425|abcd|sum
R|abc|2019-03-05|10.00
R|abc|2019-03-05|20.00
R|abc|2019-03-05|30.00
T|20200425|3|60.00
$ cat 20190306.txt
H|20200425|abcd|sum
R|abc|2019-03-06|100.00
R|abc|2019-03-06|15.00
R|abc|2019-03-06|10.00
T|20200425|3|125.00
Другое awk
решение
awk -F'[|]' '
$1=="H"{h=$0"sum"; next}
$1=="R"{o=$3".txt";gsub("-","",o);
if (! sum[o]) print h > o;
printf ("%s|%s|%s|%.2f\n", $1, $2, $3, $4) > o; sum[o]+=$4; c[o]++}
$1=="T"{for (o in sum) printf ("%s|%s|%d|%.2f\n", $1, $2, c[o], sum[o]) > o}' file;
tail -n +1 2019*.txt
Выход
==> 20190305.txt <==
H|20200425|abcd|sum
R|abc|2019-03-05|10.00
R|abc|2019-03-05|20.00
R|abc|2019-03-05|30.00
T|20200425|3|60.00
==> 20190306.txt <==
H|20200425|abcd|sum
R|abc|2019-03-06|100.00
R|abc|2019-03-06|15.00
R|abc|2019-03-06|10.00
T|20200425|3|125.00
Прохождение
Установите FS
на |
awk -F'[|]' '
Если это строка заголовка, поймайте ее, добавьте недостающий текст и перейдите к следующей строке
$1=="H"{h=$0"sum"; next}
Если это запись, возьмите $3".txt"
и разделите -
, чтобы получить имя выходного файла
$1=="R"{o=$3".txt";gsub("-","",o);
Если массив сумм для этого выходного файла еще не инициализирован, то print
заголовок файла
if (! sum[o]) print h > o;
Отформатируйте вывод, исправив последнее поле и printf
в соответствующем файле
printf ("%s|%s|%s|%.2f\n", $1, $2, $3, $4) > o;
Обновите свой sum
и запишите c
количество для этого выходного файла, используя имя файла в качестве индекса
sum[o]+=$4; c[o]++}
Если это хвостовик, итерация по массиву суммы для восстановления имен файлов, составление и printf
итоговая строка, относящаяся к каждому o
выходному файлу
$1=="T"{for (o in sum) printf ("%s|%s|%d|%.2f\n", $1, $2, c[o], sum[o]) > o}' file;
Показать вывод
tail -n +1 2019*.txt