- 标头以 H 开头
- 预告片以 T 开头
- 记录以 R 开头
- 由“|”分隔
输入文件样本
- 预告片记录第三列是记录数,第四列是金额列的总和
- 分割后,预告片应添加到新文件中,格式如下,包含计数和总和列
- INPUT 记录不会遵循日期顺序。例如:第一个记录的记录为 2019-03-05,最后一条记录也是同一日期。
输入文件:
H|20200425|abcd|sum
R|abc|2019-03-05|10.00
R|abc|2019-03-05|20.00
R|abc|2019-03-06|10.00
R|abc|2019-03-05|30.00
R|abc|2019-03-06|100.00
R|abc|2019-03-06|15.00
R|abc|2019-03-06|10.00
R|abc|2019-03-05|30.00
T|20200425|8|225.00
预期产出
文件 1:应另存为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
R|abc|2019-03-05|30.00
T|20200425|4|90.00
文件 2:应另存为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
R|abc|2019-03-06|10.00
T|20200425|4|135.00
答案1
另一种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
答案2
你可以这样做awk
:
if($0 ~ /^$/){next};
→ 忽略空行
if(NR==1){hd=$0;h=1;next}
→ 将标题存储在'高清'变量并转到下一行进行解析。
f=$3$4$5
→ 将文件名存储在'F'变量(因为“-”也是一个分隔符,它的值被分隔并且可用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
答案3
你可以试试这个:
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