Разделить файл на отдельные файлы в зависимости от содержимого столбца + добавить заголовок и записать итоги для каждого нового файла

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 КБ, но я предполагаю, что это связано с некоторой внутренней структурой файловой системы, которая по какой-то причине не считается «используемой».)

-2
28.04.2020, 13:02
3 ответа

Вы можете сделать это в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
0
19.03.2021, 02:25

Вы можете попробовать это:

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
-1
19.03.2021, 02:25

Другое 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
1
19.03.2021, 02:25

Теги

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