реорганизация файла данных

У меня есть .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
задан 13 December 2015 в 19:24

2 ответа

Если я понимаю правильно, Вы в основном хотите удалить все разрывы строки, которые не происходят непосредственно после a ;. Если так, можно сделать:

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

Или, для редактирования файла на месте использовать -i:

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

Вышеупомянутое внесет изменения в file и создайте резервное копирование названного оригинала file.bak. Для пропуска создания резервного копирования просто используют -i один, без расширения.

Объяснение

-p означает, "печатают каждую входную строку после применения сценария, данного -e. s/// оператор замены. Его общий формат s/pattern/replacement/ и заменит pattern с replacement.

В этом случае, pattern 0 или больше пробельных символов (\s*) сопровождаемый новой строкой (\n) которым не предшествует a ;. (?<!foo)bar конструкция является отрицательным lookbehind, она будет соответствовать bar если предыдущие символы не foo. Поэтому сценарий выше удалит все новые строки, которые не являются сразу после a ;.

2
ответ дан 7 December 2019 в 12:42

Сценарий ниже должен сделать задание. Так как это читает на строку, это должно быть относительно быстро на больших файлах, но не протестировало его на большом файле.

#!/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>
    

Объяснение

Сценарий читает строки, линию за линией. Если строка запускается с a 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

На относительно большом файле, 550 МБ, 9 006 121 строке:

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

На меньшем файле, 51 КБ, 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 более оптимальный вариант.

1
ответ дан 7 December 2019 в 12:42

Другие вопросы по тегам:

Похожие вопросы: