gpt4 book ai didi

linux - 使用awk处理多个文件

转载 作者:IT王子 更新时间:2023-10-29 01:13:38 24 4
gpt4 key购买 nike

我必须使用 awk 处理大量 txt 文件(每个文件有 1600 万行)。例如,我必须阅读十个文件:

文件#1:

en sample_1 200
en.n sample_2 10
en sample_3 10

文件#2:

en sample_1 10
en sample_3 67

文件#3:

en sample_1 1
en.n sample_2 10
en sample_4 20

...

我想要这样的输出:

source title f1 f2 f3 sum(f1,f2,f3)

en sample_1 200 10 1 211
en.n sample_2 10 0 10 20
en sample_3 10 67 0 77
en sample_4 0 0 20 20

这是我的第一个版本的代码:

#! /bin/bash
clear
#var declaration
BASEPATH=<path_to_file>
YEAR="2014"
RES_FOLDER="processed"
FINAL_RES="2014_06_01"
#results folder creation
mkdir $RES_FOLDER
#processing
awk 'NF>0{a[$1" "$2]=a[$1" "$2]" "$3}END{for(i in a){print i a[i]}}' $BASEPATH/$YEAR/* > $RES_FOLDER/$FINAL_RES

这里是我的输出:

en sample_1 200 10 1
en.n sample_2 10 10
en sample_3 10 67
en sample_4 20

我对如何将零列放在未发现事件的地方以及如何获得所有值的总和感到有点困惑。我知道我必须使用这个:

{tot[$1" "$2]+=$3} END{for (key in tot) print key, tot[key]}

希望有人能帮忙。谢谢。

********* 已编辑 ********

我正在尝试以不同的方式实现我的结果。我创建了一个这样的 bash 脚本,它生成了一个包含我所有 key 的排序文件,它非常庞大,大约有 6200 万条记录,我将这个文件分成多个部分,然后将每个部分传递给我的 awk 脚本。

巴什:

#! /bin/bash
clear
FILENAME=<result>
BASEPATH=<base_path>
mkdir processed/slice
cat $BASEPATH/dataset/* | cut -d' ' -f1,2 > $BASEPATH/processed/aggr
sort -u -k2 $BASEPATH/processed/aggr > $BASEPATH/processed/sorted
split -d -l 1000000 processed/sorted processed/slice/slice-
echo $(date "+START PROCESSING DATE: %d/%m/%y - TIME: %H:%M:%S")
for filename in processed/slice/*; do
awk -v filename="$filename" -f algorithm.awk dataset/* >> processed/$FILENAME
done
echo $(date "+END PROCESSING DATE: %d/%m/%y - TIME: %H:%M:%S")
rm $BASEPATH/processed/aggr
rm $BASEPATH/processed/sorted
rm -rf $BASEPATH/processed/slice

AWK:

BEGIN{
while(getline < filename){
key=$1" "$2;
sources[key];
for(i=1;i<11;i++){
keys[key"-"i] = "0";
}
}
close(filename);
}
{
if(FNR==1){
ARGIND++;
}
key=$1" "$2;
keys[key"-"ARGIND] = $3
}END{
for (s in sources) {
sum = 0
printf "%s", s
for (j=1;j<11;j++) {
printf "%s%s", OFS, keys[s"-"j]
sum += keys[s"-"j]
}
print " "sum
}
}

我使用 awk 预分配我的最终数组,并读取 dataset/* 文件夹我填充它的内容。我发现我的瓶颈来自于通过 awk 输入迭代数据集文件夹(10 个文件,每个文件有 16.000.000 行)。一切都在一小部分数据上工作,但对于真实数据,RAM (30GB) 很拥挤。有人有什么建议或建议吗?谢谢。

最佳答案

$ cat tst.awk
{
key = $1" "$2
keys[key]
val[key,ARGIND] = $3
}
END {
for (key in keys) {
sum = 0
printf "%s", key
for (fileNr=1;fileNr<=ARGIND;fileNr++) {
printf "%s%s", OFS, val[key,fileNr]+0
sum += val[key,fileNr]
}
print sum
}
}

$ awk -f tst.awk file1 file2 file3
en sample_4 0 0 2020
en.n sample_2 10 0 1020
en sample_1 200 10 1211
en sample_3 10 67 077

上面使用 GNU awk 作为 ARGIND,其他 awk 只需在开头添加一行 FNR==1{ARGIND++}。如有必要,将输出通过管道传输到 sort

关于linux - 使用awk处理多个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33978240/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com