Shell 如何平均不同文件的值并将其保存到新文件中
我有大约140个包含数据的文件,我想用脚本处理这些文件 这些文件有两种类型的名称:Shell 如何平均不同文件的值并将其保存到新文件中,shell,awk,Shell,Awk,我有大约140个包含数据的文件,我想用脚本处理这些文件 这些文件有两种类型的名称: sys-time-4-16-80-15-1-1.txt known-ratio-4-16-80-15-1-1.txt 最后两个数字不同的地方。倒数第二个数字是1,50,100,150,…,300,最后一个数字的范围是1,2,3,4,5…,10。下面是这些文件的一个示例 我想写一个包含3列的新文件,如下所示: 文件倒数第二列的第一列,即1,25,50。。。 第二列,每个sys time-..文件中第二列的平均值。
sys-time-4-16-80-15-1-1.txt
known-ratio-4-16-80-15-1-1.txt
sys time-..
文件中第二列的平均值。
第三列,每个已知比率-…
文件中第二列的平均值
对于sys
和known
文件的每对平均2nd列,结果可能有一行:
1 mean-sys-1 mean-know-1
1 mean-sys-2 mean-know-2
.
.
1 mean-sys-10 mean-know-10
50 mean-sys-1 mean-know-1
50 mean-sys-2 mean-know-2
.
.
50 mean-sys-10 mean-know-10
100 mean-sys-1 mean-know-1
100 mean-sys-2 mean-know-2
.
.
100 mean-sys-10 mean-know-10
....
....
300 mean-sys-10 mean-know-10
其中每一行对应于最后两个数字相同的sys
和known
文件。
此外,我想在第一列复制倒数第二个文件
我知道如何使用awk
计算文件第二列的平均值:
awk '{ sum += $2; n++ } END { if (n > 0) print sum / n; }' sys-time-4-16-80-15-1-5.txt
但我不知道如何迭代所有文件,并构建一个包含上述三列的结果文件 我使用GNU Awk实现了简单的每个文件操作。这是未经检验的;请让我知道它是如何运行的。您可能需要查看printf()
以获得漂亮的打印输出
mapfile -t Files < <(find . -type f -name "*-4-16-80-15-*" |sort -t\- -k7,7 -k8,8) #1
gawk '
BEGINFILE {n=split(FILENAME, f, "-"); type=f[1]; a[type]=0} #2
{a[type] = ($2 + a[type] * c++) / c} #3
ENDFILE {if(type=="sys") print f[n], a[sys], a[known]} #4
' "${Files[@]}"
在每个文件的开头,清除任何现有的平均值,并将类型保存为“sys”或“known”
在每一行上,计算
在每个文件的末尾,检查文件类型。如果我们只是处理一个“sys”文件,那么打印文件名的最后一部分,然后是我们的平均值
我使用GNU Awk实现了简单的每个文件操作。这是未经检验的;请让我知道它是如何运行的。您可能需要查看printf()
以获得漂亮的打印输出
mapfile -t Files < <(find . -type f -name "*-4-16-80-15-*" |sort -t\- -k7,7 -k8,8) #1
gawk '
BEGINFILE {n=split(FILENAME, f, "-"); type=f[1]; a[type]=0} #2
{a[type] = ($2 + a[type] * c++) / c} #3
ENDFILE {if(type=="sys") print f[n], a[sys], a[known]} #4
' "${Files[@]}"
在每个文件的开头,清除任何现有的平均值,并将类型保存为“sys”或“known”
在每一行上,计算
在每个文件的末尾,检查文件类型。如果我们只是处理一个“sys”文件,那么打印文件名的最后一部分,然后是我们的平均值
下面是一个用于计算平均值的shell脚本(如果需要,您可以很容易地切换到awk;我更喜欢使用datamash来计算统计数据):
#/垃圾箱/垃圾箱
nums=$(mktemp)
sysmeans=$(mktemp)
knownmeans=$(mktemp)
对于系统时间中的系统时间-*.txt
做
knownratio=$(echo-n“$systime”| sed-e's/sys time/known ratio/)
echo“$systime”| sed-E的/*-([0-9]+)-[0-9]+\.txt/\1/'>>“$nums”
datamash-W平均值2<“$systime”>>“$sysmeans”
datamash-W平均值2<“$knownratio”>>“$knownmeans”
完成
粘贴“$nums”$sysmeans“$knownmeans”
rm-f“$nums”$sys表示“$knownmeans”
它创建三个临时文件,每列一个,在用每对文件的数据填充它们之后,每行一对,使用粘贴将它们组合起来,并将结果打印到标准输出。下面是一个用于计算平均值的shell脚本(如果需要,您可以轻松地切换到awk;我更喜欢datamash来计算统计数据):
!/bin/sh
nums=$(mktemp)
sysmeans=$(mktemp)
knownmeans=$(mktemp)
对于系统时间中的系统时间-*.txt
做
knownratio=$(echo-n“$systime”| sed-e's/sys time/known ratio/)
echo“$systime”| sed-E的/*-([0-9]+)-[0-9]+\.txt/\1/'>>“$nums”
datamash-W平均值2<“$systime”>>“$sysmeans”
datamash-W平均值2<“$knownratio”>>“$knownmeans”
完成
粘贴“$nums”$sysmeans“$knownmeans”
rm-f“$nums”$sys表示“$knownmeans”
它创建了三个临时文件,每列一个,在用每对文件中的数据填充它们之后,每行一对,使用粘贴将它们组合起来,并将结果打印到标准输出。@vintnes您是对的。链接的名称中有倒数第二个值1、50、100、150、200。上面的示例仅此而已一个简短的文件示例。我想在链接的所有文件中运行脚本。@vintnes你说得对。链接名称中倒数第二个值为1、50、100、150、200。上面的示例只是一个简短的文件示例。我想在链接的所有文件中运行脚本。谢谢。我不知道datamash
。可以吗询问您如何更改脚本以使用两个不同文件夹中的文件(名称相同)。@user1993416使用basename
命令将非常有用。谢谢。我不知道datamash
。我可以问您如何更改脚本以使用文件(名称相同)从两个不同的文件夹@user1993416使用basename
命令将非常有用。