У меня есть .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;
(все в одной строке) и так далее для целого документа.
Если я понимаю правильно, Вы в основном хотите удалить все разрывы строки, которые не происходят непосредственно после 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 ;
.
Сценарий ниже должен сделать задание. Так как это читает на строку, это должно быть относительно быстро на больших файлах, но не протестировало его на большом файле.
#!/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 = "")
На относительно большом файле, 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
более оптимальный вариант.