数据文件重组

数据文件重组

我有一个 .data,我需要重新组织它,以便将 3 个连续的行合并为一行。为了清楚起见,我有以下内容...

D611102 = 'SVM_PRS_Hydr_L01', T = 0.0,
C = 3.341441E-006 * Cp_SVM_PRS_Pi001 * Dens_SVM_PRS_Pi001,
A = 0.007425, ALP = 1.000000, EPS = 1.000000,
FX = -0.355305, FY = 0.857782, FZ = 0.282590;

...等等

我需要将所有内容放在一行中:

D611102 = 'SVM_PRS_Hydr_L01', T = 0.0,C = 3.341441E-006 * Cp_SVM_PRS_Pi001 ...

我需要它来查看整个文档。有没有快速的方法?

另一个困难是,所有要合并的信息有时在 3 行,有时在 2 行或 4 行。我唯一能想到的是每行都用 D 来标识……可以做到吗?怎么做?

基本上,每行新行都应以节点号 D611102 开头。我需要一行大行,其中 T = ...、C = ...,直到 FZ = .... 等。每行都必须包含直到 ; 的所有数据

为了更清楚,我有以下内容:......

   D611102 = 'SVM_PRS_Hydr_L01', T = 0.0,
     C = 3.341441E-006 * Cp_SVM_PRS_Pi001 * Dens_SVM_PRS_Pi001,
     A = 0.007425, ALP = 1.000000, EPS = 1.000000,
     FX = -0.355305, FY = 0.857782, FZ = 0.282590;
    D611103 = 'SVM_PRS_Hydr_L01', T = 0.0,
     C = 3.341441E-006 * Cp_SVM_PRS_Pi001 * Dens_SVM_PRS_Pi001,
     A = 0.007425, ALP = 1.000000, EPS = 1.000000,
     FX = -0.656518, FY = 0.656518, FZ = 0.282590;

...等等...我需要这个:

D611102 = 'SVM_PRS_Hydr_L01', T = 0.0,C = 3.341441E-006 * Cp_SVM_PRS_Pi001 * Dens_SVM_PRS_Pi001,A = 0.007425, ALP = 1.000000, EPS = 1.000000,FX = -0.355305, FY = 0.857782, FZ = 0.282590; (all in a single line)
D611103 = 'SVM_PRS_Hydr_L01', T = 0.0,C = 3.341441E-006 * Cp_SVM_PRS_Pi001 * Dens_SVM_PRS_Pi001,A = 0.007425, ALP = 1.000000, EPS = 1.000000,FX = -0.656518, FY = 0.656518, FZ = 0.282590; 

(所有内容都在一行中),整个文档也是如此。

答案1

如果我理解正确的话,你基本上想要删除所有不直接出现在 之后的换行符;。如果是这样,你可以这样做:

perl -pe 's/(?<!;)\s*\n/ /' file > newfile

或者,要就地编辑文件,请使用-i

perl -i.bak -pe 's/(?<!;)\s*\n/ /' file

上述操作将对 进行更改file并创建原始的备份,名为file.bak。若要跳过创建备份,只需-i单独使用,无需扩展名。

解释

的意思-p是“应用 给出的脚本后打印每一行输入-es///是替换运算符。它的一般格式是s/pattern/replacement/并将 替换patternreplacement

在这种情况下,pattern是 0 个或更多空格字符 ( \s*),后跟换行符 ( \n),且前面没有;。该(?<!foo)bar构造是负面后视bar,如果前面的字符不是 ,它将匹配foo。因此,上面的脚本将删除所有不在 之后的换行符;

答案2

下面的脚本应该可以完成这项工作。由于它是按行读取的,因此在处理较大的文件时应该相对较快,但我没有在大型文件上进行测试。

#!/usr/bin/env python3
import sys

f = sys.argv[1]

s = ""

with open(f) as lines:
    for l in  lines:
        if l.startswith("D"):
            print(s+l.strip(), end = "")
            s = "\n"
        else:
            print(l.strip(), end = "")

用它

  • 将其复制到空文件中,另存为combine_lines.py
  • 通过命令运行:

    python3 /path/to/combine_lines.py <.data_file>
    

解释

脚本逐行读取行。如果行以 开头D,则该行将打印在现有行之后,除了第一行。

测试:

D611102 = 'SVM_PRS_Hydr_L01', T = 0.0,C = 3.341441E-006 * Cp_SVM_PRS_Pi001 * Dens_SVM_PRS_Pi001,
A = 0.007425, ALP = 1.000000, EPS = 1.000000,
FX = -0.355305, FY = 0.857782, FZ = 0.282590;
D611102 = 'SVM_PRS_Hydr_L01', T = 0.0,C = 3.341441E-006 * Cp_SVM_PRS_Pi001 * Dens_SVM_PRS_Pi001,
A = 0.007425, ALP = 1.000000, EPS = 1.000000,
FX = -0.355305, FY = 0.857782, FZ = 0.282590;

变成:

D611102 = 'SVM_PRS_Hydr_L01', T = 0.0,C = 3.341441E-006 * Cp_SVM_PRS_Pi001 * Dens_SVM_PRS_Pi001,A = 0.007425, ALP = 1.000000, EPS = 1.000000,FX = -0.355305, FY = 0.857782, FZ = 0.282590;
D611102 = 'SVM_PRS_Hydr_L01', T = 0.0,C = 3.341441E-006 * Cp_SVM_PRS_Pi001 * Dens_SVM_PRS_Pi001,A = 0.007425, ALP = 1.000000, EPS = 1.000000,FX = -0.355305, FY = 0.857782, FZ = 0.282590;

编辑

或者,

按照@terdon的建议,使用结尾的“;”作为触发器,这使我们有机会跳过这个s =技巧:

#!/usr/bin/env python3
import sys

f = sys.argv[1]

with open(f) as lines:
    for l in  lines:
        l = l if l.endswith(";\n") else l.strip(); print(l, end = "")

Perl 与 Python 的比较

在一个相对较大的文件上,550MB,9006121 行:

Perl:

$ time perl -pe 's/(?<!;)\s*\n/ /' '/home/jacob/Bureaublad/data_large' > '/home/jacob/Bureaublad/data_large2'

real    0m27.171s
user    0m25.536s
sys     0m1.054s

Python:

time '/home/jacob/Bureaublad/pscript_9.py' '/home/jacob/Bureaublad/data_large' > '/home/jacob/Bureaublad/data_large2'

real    0m15.235s
user    0m13.806s
sys     0m1.279s

在较小的文件(51KB,838 行)上:

$ time perl -pe 's/(?<!;)\s*\n/ /' '/home/jacob/Bureaublad/data_small' > '/home/jacob/Bureaublad/data_small2' 

real    0m0.008s
user    0m0.007s
sys     0m0.000s

Python:

$ time '/home/jacob/Bureaublad/pscript_9.py' '/home/jacob/Bureaublad/data_small' > '/home/jacob/Bureaublad/data_small2' 

real    0m0.033s
user    0m0.019s
sys     0m0.011s

底线是,如果您有更大的文件,python可能这就是您想要使用的,如果您有许多较小的文件,Perl则是更好的选择。

相关内容