gpt4 book ai didi

linux - 如何根据原始文件的第一列值组织新文件?

转载 作者:太空宇宙 更新时间:2023-11-04 09:27:00 25 4
gpt4 key购买 nike

假设我有 3 个文件:File-AFile-BFile-C;其中每个文件有两列数据(空间划定)但行数未知(且可变)。

输入

File-A:
1 dE
1 dF
2 dF
2 dH

File-B:
1 dI
3 dJ
3 dK

File-C:
2 dF
3 dH
3 dJ
3 dK
4 dL

我如何有效地对数据进行排序,以便为第一列中的每个值创建新文件(即,File-1File-2 File-3, File-4) 跟踪他们的第 2 列合作伙伴数据和原始文件名?

期望的输出

File-1:      
A dE
A dF
B dI

File-2:
A dF
A dH
C dF

File-3:
B dJ
B dK
C dH
C dJ
C dK

File4:
C dL

实际上,我有几十万个原始文件,每个文件有几百行数据(但原始文件和新文件的总数是已知的)。实现此类排序最省时的方法是什么?

与 Fortran 之类的程序相比,Bash 脚本是否是最快的方法?我刚开始学习 sed 和 awk – 这样的东西效果最好吗?

如果在链接之前提出了类似的问题,我们将不胜感激。 closest question到目前为止,我发现 awk 似乎是一种可行的方法。

最佳答案

这是一个(可能非常慢的)Bash 解决方案:

#!/bin/bash

for suffix in "${@##*-}"; do # Get suffix from each file name
while read -r col1 col2; do # Read two columns

# Assemble output line and write to proper file
printf "%s %s\n" "$suffix" "$col2" >> "File-$col1"
done < "File-$suffix"
done

Bash 循环很慢,许多重定向也很慢,但我想不出另一种方法,因为每个输入行都可能转到另一个输出文件。

awk 中可能更快的东西:

#!/usr/bin/awk -f

# For each new file, get the file name suffix
FNR == 1 {
split(FILENAME, arr, "-")
suffix = arr[2]
}

# On each line, create the output file name, then print to that file
{
ofname = "File-" $1
print suffix, $2 > ofname
}

两者都是从命令行使用 ./scriptname File-* 调用的。

打开文件句柄的数量限制

可以同时打开的文件句柄数量是有限制的:从您的操作系统和 awk。 Gawk 做了一些技巧1 来解决这个问题,但它可能仍然更快(并且绝对更便携)以避免打开的文件句柄太多。

例如,一种补救措施是跟踪每个输入文件的打开文件句柄,然后在处理下一个文件之前关闭它们:

#!/usr/bin/awk -f

# For each new file, get the file name suffix
FNR == 1 {
# Close open files
for (fname in openfiles)
close(openfiles[fname])
split(FILENAME, arr, "-")
suffix = arr[2]
}

# On each line, create the output file name, then print to that file
{
ofname = "File-" $1
openfiles[ofname] = 1 # Keep track of open files
print suffix, $2 > ofname
}

1 来自 manual :

If you use more files than the system allows you to have open, gawk attempts to multiplex the available open files among your data files. gawk’s ability to do this depends upon the facilities of your operating system, so it may not always work.

It is therefore both good practice and good portability advice to always use close() on your files when you are done with them. In fact, if you are using a lot of pipes, it is essential that you close commands when done.

关于linux - 如何根据原始文件的第一列值组织新文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35373544/

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