Как записать Perl измененный контент в файл в Python скриптах? - PullRequest
0 голосов
/ 16 февраля 2020

Мои данные исследований не являются обычным файлом. Номер столбца каждой строки может отличаться. Я хочу преобразовать файл "dat" в файл "* .csv", используя Perl, потому что он может работать эффективно (у меня плохой опыт работы с Python). Ниже приведен скрипт, который я запустил. Он отлично работает в Linux, но не выводит контекст в Python сценариях.

new_dat_file="14689_bondlength.prmfrm.dat"
new_csv_file="14689_bondlength.prmfrm.csv"
perl -p -e 's/\\t\s+|\s+/,/g' $new_dat_file |perl -p -e 's/,FRAM/\\nFRAM/g' >  $new_csv_file

Выше коды работают в Linux. Я улучшил их в Python скриптах. Если я использую приведенную ниже команду

import os
new_dat_file="14689_bondlength.prmfrm.dat"
new_csv_file="14689_bondlength.prmfrm.csv"
cmd = "perl -p -e 's/\\t\s+|\s+/,/g' " + new_dat_file + " |perl -p -e 's/,FRAM/\\nFRAM/g' 
os.system(cmd)

, я могу видеть вывод правильно. Однако, если я изменю значения cmd, как показано ниже, чтобы сохранить вывод в файл csv, но я получил пустой файл.

cmd = "perl -p -e 's/\\t\s+|\s+/,/g' " + new_dat_file + " |perl -p -e 's/,FRAM/\\nFRAM/g' > " + new_csv_file

Как я могу исправить эту проблему? Если я не могу сделать это, есть ли другой альтернативный способ? Любые дальнейшие предложения будут высоко оценены.

Кстати: частичные данные перечислены ниже

FRAM_#            0            0(fs)  CN= 1 PRMRYTGT     14689      H      15449      O  1.008
FRAM_#          100           25(fs)  CN= 1 PRMRYTGT     14689      H      15449      O  0.955
FRAM_#          200           50(fs)  CN= 1 PRMRYTGT     14689      H      15449      O  0.993
FRAM_#          300           75(fs)  CN= 1 PRMRYTGT     14689      H      15449      O  0.973
FRAM_#          400          100(fs)  CN= 1 PRMRYTGT     14689      H      15449      O  0.988
FRAM_#          500          125(fs)  CN= 1 PRMRYTGT     14689      H      15449      O  1.033
FRAM_#          600          150(fs)  CN= 1 PRMRYTGT     14689      H      15449      O  1.032
FRAM_#          700          175(fs)  CN= 1 PRMRYTGT     14689      H      15449      O  0.986
FRAM_#          800          200(fs)  CN= 1 PRMRYTGT     14689      H      15449      O  1.061
FRAM_#          900          225(fs)  CN= 1 PRMRYTGT     14689      H      15449      O  1.078
FRAM_#         1000          250(fs)  CN= 1 PRMRYTGT     14689      H      15449      O  0.922
FRAM_#         1100          275(fs)  CN= 2 PRMRYTGT     14689      H      17402      O  1.257     15449      O  1.430
FRAM_#       303200        75800(fs)  CN= 0 PRMRYTGT_BD     14689      H
FRAM_#       921200       230300(fs)  CN= 1 PRMRYTGT_BD     14689      H        8375      O  1.062
FRAM_#      1078700       269675(fs)  CN= 1 PRMRYTGT_BD     14689      H       12971      O  1.507
FRAM_#     18203400      4550850(fs)  CN= 1 PRMRYTGT_BD     14689      H       16172      O  1.507

Я надеюсь получить вывод, как показано ниже:

FRAM_#,0,0(fs),CN=,1,PRMRYTGT,14689,H,15449,O,1.008
FRAM_#,100,25(fs),CN=,1,PRMRYTGT,14689,H,15449,O,0.955
FRAM_#,200,50(fs),CN=,1,PRMRYTGT,14689,H,15449,O,0.993
FRAM_#,300,75(fs),CN=,1,PRMRYTGT,14689,H,15449,O,0.973
FRAM_#,400,100(fs),CN=,1,PRMRYTGT,14689,H,15449,O,0.988
FRAM_#,500,125(fs),CN=,1,PRMRYTGT,14689,H,15449,O,1.033
FRAM_#,600,150(fs),CN=,1,PRMRYTGT,14689,H,15449,O,1.032
FRAM_#,700,175(fs),CN=,1,PRMRYTGT,14689,H,15449,O,0.986
FRAM_#,800,200(fs),CN=,1,PRMRYTGT,14689,H,15449,O,1.061
FRAM_#,900,225(fs),CN=,1,PRMRYTGT,14689,H,15449,O,1.078
FRAM_#,1000,250(fs),CN=,1,PRMRYTGT,14689,H,15449,O,0.922
FRAM_#,1100,275(fs),CN=,2,PRMRYTGT,14689,H,17402,O,1.257,15449,O,1.430

Ответы [ 3 ]

2 голосов
/ 16 февраля 2020

Это легко сделать за perl. Напомним, \s включает в себя \n\t\r. Вам нужно \h, которое представляет собой любое горизонтальное пространство и не включает перевод строки

, просто сделайте

 perl -pe 's/\h+/,/g' $new_dat_file > $new_csv_file
2 голосов
/ 16 февраля 2020

Боюсь, ваши Perl навыки написания скриптов тоже немного ограничены. В любом случае, все это достаточно просто сделать в Python.

import re

new_dat_file = "14689_bondlength.prmfrm.dat"
new_csv_file = "14689_bondlength.prmfrm.csv"
with open(new_dat_file) as input, open(new_csv_file, 'w') as output:
    for line in input:
        line = line.rstrip('\n')
        line = re.sub(r'\\t\s+|\s+', ',', line)
        # line = line.replace(',FRAM', r'\\nFRAM')
        output.write(line + '\n')

Двойные обратные слеши выглядят подозрительно, но я предполагаю, что это действительно то, что вы на самом деле хотите. \\t - это обратная косая черта sh и строчная буква t, тогда как \t представляет собой табуляцию.

Я обновил это, чтобы отключить финальный символ новой строки, а затем вернул его после замены регулярного выражения. При этом нет необходимости ставить новую строку перед FRAM.

Если бы вы действительно, действительно хотели использовать внешний процесс, я бы go с

import subprocess

with open(new_dat_file) as input, open(new_csv_file, 'w') as output:
    subprocess.run(['perl', '-p', '-e', 's/\\t\s+|\s+/,/g; s/,FRAM/\\nFRAM/g'],
    stidin=input, stdout=output, check=True)

и возможно, аналогично приведенному выше, переключитесь на perl -l, чтобы не заменять символы новой строки, поэтому вам придется снова их вернуть.

0 голосов
/ 17 февраля 2020

Эта задача очень проста - заменить все последовательные пробелы [+] на запятую [,] - выполнено.

use strict;
use warnings;
use feature 'say';

my $infile  = shift || die 'Provide input file';
my $outfile = shift || die 'Provide output file';

my $fh;     # filehandle

open $fh, '<', $infile
    or die "Couldn't open $infile";

my @data = <$fh>;

close $fh;

open $fh, '>', $outfile
    or die "Couldn't open $outfile";

for (@data) {
    chomp;
    s/ +/,/g;
    say $fh $_;
}

close $fh;

Вывод

FRAM_#,0,0(fs),CN=,1,PRMRYTGT,14689,H,15449,O,1.008
FRAM_#,100,25(fs),CN=,1,PRMRYTGT,14689,H,15449,O,0.955
FRAM_#,200,50(fs),CN=,1,PRMRYTGT,14689,H,15449,O,0.993
FRAM_#,300,75(fs),CN=,1,PRMRYTGT,14689,H,15449,O,0.973
FRAM_#,400,100(fs),CN=,1,PRMRYTGT,14689,H,15449,O,0.988
FRAM_#,500,125(fs),CN=,1,PRMRYTGT,14689,H,15449,O,1.033
FRAM_#,600,150(fs),CN=,1,PRMRYTGT,14689,H,15449,O,1.032
FRAM_#,700,175(fs),CN=,1,PRMRYTGT,14689,H,15449,O,0.986
FRAM_#,800,200(fs),CN=,1,PRMRYTGT,14689,H,15449,O,1.061
FRAM_#,900,225(fs),CN=,1,PRMRYTGT,14689,H,15449,O,1.078
FRAM_#,1000,250(fs),CN=,1,PRMRYTGT,14689,H,15449,O,0.922
FRAM_#,1100,275(fs),CN=,2,PRMRYTGT,14689,H,17402,O,1.257,15449,O,1.430
FRAM_#,303200,75800(fs),CN=,0,PRMRYTGT_BD,14689,H
FRAM_#,921200,230300(fs),CN=,1,PRMRYTGT_BD,14689,H,8375,O,1.062
FRAM_#,1078700,269675(fs),CN=,1,PRMRYTGT_BD,14689,H,12971,O,1.507
FRAM_#,18203400,4550850(fs),CN=,1,PRMRYTGT_BD,14689,H,16172,O,1.507
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...