txt fileからの座標抽出

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
mo-fu

txt fileからの座標抽出

#1

投稿記事 by mo-fu » 12年前

いつもここの方々には手助けをいただいております。
今回もすこしご助力願おうと思いまして、質問させていただきます。

今私の手元に

コード:

{ 
  s_m_m2io_version
  :::
  2.0.0 
} 

f_m_ct { 
  s_m_title
  s_m_job_name
  r_mmod_Potential_Energy-MMFF94s
  b_mmod_Minimization_Converged-MMFF94s
  r_mmod_RMS_Derivative-MMFF94s
  i_mmod_Times_Found-MMFF94s
  r_mmod_Relative_Potential_Energy-MMFF94s
  s_m_entry_name
  :::
  meta 
  mmod_multmini_meta_2opt 
      471.182922363281 
  1     
    0.0258791297674179 
  2     
    20.2645874023438 
  meta-inc1.1-inc1
  m_depend[5] { 
    # First column is dependency index #
    i_m_depend_dependency
    s_m_depend_property
    :::
    1         20 r_mmod_Potential_Energy-MMFF94s 
    2         20 b_mmod_Minimization_Converged-MMFF94s 
    3         20 r_mmod_RMS_Derivative-MMFF94s 
    4         20 i_mmod_Times_Found-MMFF94s 
    5         20 r_mmod_Relative_Potential_Energy-MMFF94s 
    :::
  } 
  m_atom[56] { 
    # First column is atom index #
    i_m_mmod_type
    r_m_x_coord
    r_m_y_coord
    r_m_z_coord
    i_m_residue_number
    s_m_insertion_code
    s_m_mmod_res
    s_m_chain_name
    i_m_color
    r_m_charge1
    r_m_charge2
    s_m_pdb_residue_name
    s_m_pdb_atom_name
    s_m_grow_name
    i_m_atomic_number
    i_m_formal_charge
    i_m_representation
    i_m_visibility
    s_m_atom_name
    i_m_template_index
    :::
    1        3   -3.309070   -0.370477   -2.267719     1 " " X " "    2   0.28000   0.28000 "    " "    " "  c1"    6   0    0    1 C1 0     
    2       41   -4.257547    0.128566   -2.489907     1 " " X " "   21   0.00000   0.00000 "    " "    " "  c2"    1   0    0    1 H2 0     
    3       41   -3.345572   -1.408845   -2.616174     1 " " X " "   21   0.00000   0.00000 "    " "    " "  n2"    1   0    0    1 H3 0     
    4        3   -2.149850    0.363637   -2.940698     1 " " X " "    2   0.28000   0.28000 "    " "    " "  c1"    6   0    0    1 C5 0     
    5       41   -2.379952    0.555992   -3.993401     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H7 0     
    6       41   -1.959116    1.311284   -2.423991     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H8 0     
    7       16   -0.988199   -0.473665   -2.881892     1 " " X " "   70  -0.56000  -0.56000 "    " "    " "  c1"    8   0    0    1 O7 0     
    8        3    0.212781    0.256270   -3.117079     1 " " X " "    2   0.28000   0.28000 "    " "    " "  c1"    6   0    0    1 C11 0     
    9       41    0.206505    0.677738   -4.128855     1 " " X " "   21   0.00000   0.00000 "    " "    " "  n2"    1   0    0    1 H12 0     
    10      41    0.290258    1.087620   -2.408064     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H13 0     
    11      16   -3.102861   -0.332585   -0.851278     1 " " X " "   70  -0.56000  -0.56000 "    " "    " "  c1"    8   0    0    1 O13 0     
    12       3   -3.900382   -1.290885   -0.154419     1 " " X " "    2   0.28000   0.28000 "    " "    " "  c1"    6   0    0    1 C17 0     
    13      41   -4.952574   -1.010686   -0.271212     1 " " X " "   21   0.00000   0.00000 "    " "    " "  n2"    1   0    0    1 H18 0     
    14      41   -3.732967   -2.288266   -0.575925     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H19 0     
    15       3   -3.524024   -1.285101    1.330792     1 " " X " "    2   0.28000   0.28000 "    " "    " "  c1"    6   0    0    1 C20 0     
    16      41   -3.408531   -0.265834    1.716678     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H22 0     
    17      41   -4.327471   -1.770822    1.894096     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H23 0     
    18       3    1.405864   -0.681932   -2.943676     1 " " X " "    2   0.28000   0.28000 "    " "    " "  c1"    6   0    0    1 C23 0     
    19      41    1.322339   -1.195557   -1.981452     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H25 0     
    20      41    1.385438   -1.443388   -3.732419     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H26 0     
    21      16   -2.338728   -2.045921    1.606786     1 " " X " "   70  -0.56000  -0.56000 "    " "    " "  c1"    8   0    0    1 O21 0     
    22      16    2.628591    0.065597   -3.011482     1 " " X " "   70  -0.56000  -0.56000 "    " "    " "  c1"    8   0    0    1 O22 0     
    23       3   -1.140335   -1.373319    1.217970     1 " " X " "    2   0.28000   0.28000 "    " "    " "  c1"    6   0    0    1 C32 0     
    24      41   -1.103573   -1.242739    0.132706     1 " " X " "   21   0.00000   0.00000 "    " "    " "  n2"    1   0    0    1 H33 0     
    25      41   -1.092272   -0.381907    1.682663     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H34 0     
    26      41    3.592904   -1.756243   -3.380074     1 " " X " "   21   0.00000   0.00000 "    " "    " "  n2"    1   0    0    1 H36 0     
    27      41    4.576189   -0.286725   -3.501227     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H37 0     
    28       3    0.068612   -2.204882    1.639952     1 " " X " "    2   0.28000   0.28000 "    " "    " "  c1"    6   0    0    1 C30 0     
    29      41    0.002855   -3.194994    1.172727     1 " " X " "   21   0.00000   0.00000 "    " "    " "  n2"    1   0    0    1 H31 0     
    30      41    0.075835   -2.346458    2.726657     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H33 0     
    31      16    1.270429   -1.535796    1.237728     1 " " X " "   70  -0.56000  -0.56000 "    " "    " "  c1"    8   0    0    1 O33 0     
    32       3    2.416557   -2.395368    1.364512     1 " " X " "    2   0.28000   0.28000 "    " "    " "  c1"    6   0    0    1 C39 0     
    33      41    2.202828   -3.363075    0.896500     1 " " X " "   21   0.00000   0.00000 "    " "    " "  n2"    1   0    0    1 H40 0     
    34      41    2.631824   -2.537326    2.428411     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H42 0     
    35       3    3.608744   -1.743975    0.662036     1 " " X " "    2   0.28000   0.28000 "    " "    " "  c1"    6   0    0    1 C42 0     
    36      41    3.742683   -0.720454    1.027353     1 " " X " "   21   0.00000   0.00000 "    " "    " "  n2"    1   0    0    1 H43 0     
    37      41    4.520497   -2.322199    0.842703     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H44 0     
    38      16    3.342847   -1.726558   -0.744051     1 " " X " "   70  -0.56000  -0.56000 "    " "    " "  c1"    8   0    0    1 O40 0     
    39       2    2.772003    4.085752   -0.224583     2 " " X " "    2  -0.15000  -0.15000 "    " "    " "  n1"    6   0    0    1 C42 0     
    40       2    2.562328    2.819215   -0.762035     2 " " X " "    2   0.08250   0.08250 "    " "    " "    "    6   0    0    1 C43 0     
    41       2    2.106344    1.773577    0.035320     2 " " X " "    2  -0.15000  -0.15000 "    " "    " "  c3"    6   0    0    1 C44 0     
    42       2    1.879038    2.006620    1.388246     2 " " X " "    2   0.08250   0.08250 "    " "    " "  c1"    6   0    0    1 C45 0     
    43       2    2.084982    3.266422    1.941139     2 " " X " "    2  -0.15000  -0.15000 "    " "    " "    "    6   0    0    1 C46 0     
    44       2    2.530767    4.311409    1.131280     2 " " X " "    2  -0.15000  -0.15000 "    " "    " "  n3"    6   0    0    1 C47 0     
    45      41    3.124021    4.893111   -0.860134     2 " " X " "   21   0.15000   0.15000 "    " "    " "  n2"    1   0    0    1 H48 0     
    46      41    1.899400    3.432146    2.998268     2 " " X " "   21   0.15000   0.15000 "    " "    " "    "    1   0    0    1 H52 0     
    47      41    2.692601    5.298046    1.555963     2 " " X " "   21   0.15000   0.15000 "    " "    " "    "    1   0    0    1 H53 0     
    48      16    1.457040    1.008998    2.217695     2 " " X " "   70  -0.53250  -0.53250 "    " "    " "  c1"    8   0    0    1 O54 0     
    49      42    1.382569    0.177805    1.702101     2 " " X " "   21   0.45000   0.45000 "    " "    " "  n2"    1   0    0    1 H55 0     
    50       3    3.790692   -0.781078   -2.920537     1 " " X " "    2   0.28000   0.28000 "    " "    " "  c1"    6   0    0    1 C53 0     
    51       3    4.275088   -0.931547   -1.474548     1 " " X " "    2   0.28000   0.28000 "    " "    " "  c1"    6   0    0    1 C54 0     
    52      41    5.250410   -1.428980   -1.456815     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H54 0     
    53      41    4.363398    0.056739   -1.012027     1 " " X " "   21   0.00000   0.00000 "    " "    " "    "    1   0    0    1 H55 0     
    54      16    2.826508    2.645890   -2.089707     2 " " X " "   70  -0.53250  -0.53250 "    " "    " "  c1"    8   0    0    1 O56 0     
    55      42    2.701750    1.703617   -2.330007     2 " " X " "   21   0.45000   0.45000 "    " "    " "  n2"    1   0    0    1 H57 0     
    56      41    1.933087    0.789842   -0.384067     1 " " X " "   21   0.15000   0.15000 "    " "    " "  c1"    1   0    0    1 H56 0     
    :::
  } 
というtxt fileがあります。実際のファイルは17-24, 60-115行目部分の文字列や数値が違うものが数千と繰り返し記述されています。
ここから60行目から115行目の部分を抜き出して

6 -3.309070 -0.370477 -2.267719
1 -4.257547 0.128566 -2.489907
以下略
というoutputfileを作ろうと思っています。(つまり各行前から3,4,5個目の数値と後ろから6個めの数値。)
さらにひとつのカラムから56行のtxt fileが出来たら、次のカラムの56行分は別のtxt fileとして吐き出してやりたいのですがその方法が思いつきません。
さらにいうと、数値を抜き出してやるとき何を目印にしてやればいいかということも悩んでいます。 実際のファイルとしては17-24, 60-115行目以外は全て同じ文字列の繰り返しになっています。

これを実行するものとして、依然違う形式のファイルから数値を取り出す際に作成したものを元に作っていこうと思うのですが↓

コード:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>




//
// ファイル内の文字列の長さを取得する
////////////////////////////////////////////////////////////////////////////////
int GetFileLength(FILE *fp)
{
    int now_position;
    int length;
    now_position = ftell(fp); // 現在の位置を保存しておく
    fseek(fp, 0, SEEK_END); // ファイルの最後までカーソルを持っていく
    length = ftell(fp); // 現在の位置を取得する (= ファイル全体の大きさ)
 
    fseek(fp, now_position, SEEK_SET); // 最初に保存していた位置に戻す
 
    return length;
}
 
//
//文字Freqを抽出
////////////////////////////////////////////////////////////////////////////////
int VibExtract(char *str, double *vib, int n, int vib_counter)
{
    int i, len;
    for (i = vib_counter; i < n && sscanf(str, "%lf%n", &vib[i], &len) == 1; i++)
        str += len;
    return i;
}

//
// モード数を返す
////////////////////////////////////////////////////////////////////////////////
double GetFreq(FILE *fp_input, FILE *fp_output, char key[], double *vib)
{
	
    int counter = 0;
	
	int vib_counter = 0;
	int Str;
	

	
	
    int length = GetFileLength(fp_input); // ファイル全体の大きさを取得する
    char *str = (char*)calloc(length+1, sizeof(char)); // +1は文字列の最後のNULL文字を考慮
	int now_position = ftell(fp_input); // 現在の位置を保存しておく
 
    for (counter = 0;Str = fgets(str, length, fp_input) != NULL; counter++){ // EOFが来るまで一行ずつ読み込む

		if(strstr(str,key))
			 vib_counter = VibExtract(str + sizeof("Frequencies --"), vib, length, vib_counter);//関数呼び出し
	}
	fseek(fp_input, now_position, SEEK_SET); // カーソルを最初に保存した位置に戻す
 
    return vib_counter;//元counterを返していたの今回のforのインクリメントは無意味
	free(str);

}
//
//文字列からIRintensを抽出
////////////////////////////////////////////////////////////////////////////////
int IRintensExtract(char *str, double *IRintens, int n, int intens_counter)
{
    int i, len;
    for (i = intens_counter; i < n && sscanf(str, "%lf%n", &IRintens[i], &len) == 1; i++)
        str += len;
    return i;
}

//
//モード数を返す
////////////////////////////////////////////////////////////////////////////////
double GetIRintens(FILE *fp_input, FILE *fp_output, char key[], double *IRintens)
{
	
    int counter = 0;
	
	int intens_counter = 0;
	int Str;
	

	
	
    int length = GetFileLength(fp_input); // ファイル全体の大きさを取得する
    char *str = (char*)calloc(length+1, sizeof(char)); // +1は文字列の最後のNULL文字を考慮
	int now_position = ftell(fp_input); // 現在の位置を保存しておく
 
    for (counter = 0;Str = fgets(str, length, fp_input) != NULL; counter++){ // EOFが来るまで一行ずつ読み込む

		if(strstr(str,key))
			 intens_counter = IRintensExtract(str + sizeof("IR Inten    --"), IRintens, length, intens_counter);//関数呼び出し
	}
	fseek(fp_input, now_position, SEEK_SET); // カーソルを最初に保存した位置に戻す
 
    return intens_counter;//元counterを返していたの今回のforのインクリメントは無意味
	free(str);

}


void main(int args, char *argv[])
{
	FILE *fp_input, *fp_output;

	char key_freq[] = "Frequencies --";//キーワード
	char key_IRintens[] = "IR Inten    --";
	int counter = 0;
	int dummy = 0;//コマンド画面の保持用
	int freq;
	int intens;
	
	
	
	for(counter=1; args > counter; counter++){//投入したファイル数だけくりかえし

		char file_path[50];
		sprintf(file_path, "%s.frq", argv[counter]); 
		fp_output = fopen(file_path, "w");
		fp_input = fopen(argv[counter],"r");
		
		if(fp_input == NULL){
			printf("file cannot open\n");
			return;
	}

		int length = GetFileLength(fp_input); // ファイル全体の大きさを取得する
		double *vib = (double*)calloc(length+1, sizeof(double)); // +1は文字列の最後のNULL文字を考慮
		double *IRintens = (double*)calloc(length+1, sizeof(double)); // +1は文字列の最後のNULL文字を考慮
		freq = GetFreq(fp_input, fp_output, key_freq, vib);//freqにモード数を代入
		intens = GetIRintens(fp_input, fp_output, key_IRintens, IRintens);//freqと同じ値になるはず

	
	fprintf(fp_output,"Freq\tIRintens\n");
	for(dummy = 0; dummy<freq; dummy++){
		
		fprintf(fp_output,"%f\t%f\n",vib[dummy], IRintens[dummy]);
		
	}
	printf("Extract is finished %s\n",argv[counter]);
	free(vib);
	}
	fclose(fp_input);
	fclose(fp_output);
	if(args <= 2)
	{
	printf("\nJob end.The number of file is %d.\n\nEnter any key.\n\n", args-1);
	}else if(args >= 3){
	printf("\nJob end.The number of files are %d.\n\nEnter any key.\n\n", args-1);
	}
	scanf("%d", &dummy);//コマンド画面保持用

}
110行目の「キーワード」部分のように、今回のtxt fileには欲しい数値がある行に明確なキーワードを見つけてやることができません。(このプログラムに対応したファイルはFrequencies --などで簡単に指定できた)

当方化学の実験屋でして、プログラムはかじった程度なので冗長で伝わりにくい文・見難い(醜い)プログラムを見せてしまい申し訳ないのですが
御助力願えればと思います。

開発環境等は
windows7 Microsoft Visual C++2010で言語はお分かりの通りCを用いております。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: txt fileからの座標抽出

#2

投稿記事 by みけCAT » 12年前

こういう時(入力が全てわかっていて、あまりエラー処理が必要でない場合)は、
自分はPerlの正規表現で処理するのが簡単だと思います。
C++を使用しないといけない縛りですか?

コード:

#!/usr/bin/perl

while(<STDIN>) {
	$nowLine=$_;
	chomp($nowLine);
	$nowLine =~ s/^ *\d+ +\d+ +(-?[\d.]+) +(-?[\d.]+) +(-?[\d.]+).*" +(\d+)/print "$4"." "."$1 $2 $3\n"/e;
}
このコードをwork.pl、質問の入力データをinput.txtとして保存し、

コード:

work.pl < input.txt > output.txt
というコマンドを実行すれば、output.txtにデータが出力されます。

また、出力の最初の整数と次の実数の間は全角スペースでないといけないのですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: txt fileからの座標抽出

#3

投稿記事 by みけCAT » 12年前

mo-fu さんが書きました:さらにひとつのカラムから56行のtxt fileが出来たら、次のカラムの56行分は別のtxt fileとして吐き出してやりたいのですがその方法が思いつきません。
ひとつのカラムから56行のtxt fileが出来ない場合を考えると複雑そうですが(そもそもこの場合のカラムってなんだろう?)、
単純に1個の出力テキストファイルに56行書き出したら次の出力テキストファイルに移る、という処理を実装してみました。
標準入力から入力を読み込み、カレントディレクトリのoutput000.txt,output001.txt, ... に出力します。

コード:

#!/usr/bin/perl

use strict;

my $outputCounter=0;
my $outputFileCounter=0;
my $outputFileLength=56; # 分割したい行数

while(<STDIN>) {
	my $nowLine=$_;
	chomp($nowLine);
	if($nowLine =~ /^ *\d+ +\d+ +(-?[\d.]+) +(-?[\d.]+) +(-?[\d.]+).*" +(\d+)/) {
		if($outputCounter==0) {
			unless(open(OUT,sprintf("> output%03d.txt",$outputFileCounter))) {
				die sprintf("Failed to open output%03d.txt\n",$outputFileCounter);
			}
		}
		print OUT "$4"." "."$1 $2 $3\n";
		$outputCounter++;
		if($outputCounter>=$outputFileLength) {
			close(OUT);
			$outputCounter=0;
			$outputFileCounter++;
		}
	}
}
if($outputCounter>0){close(OUT);}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

mo-fu

Re: txt fileからの座標抽出

#4

投稿記事 by mo-fu » 12年前

みけCAT様

素早い返信ありがとうございます!この場合のカラムというのは、1-117行目をひとまとまりと考えたときの呼称として用いました。このまとまりが数千回繰り返されているので(;^ω^A 分かりにくくてすみません!

言語ですが、使用言語はC言語なので出来ればCだとソースを読んだときに自分でも理解できるのでありがたいです。これももう少し目立つところに明記するべきでしたねΣ(゜Д゜;≡;゜д゜)!

mo-fu

Re: txt fileからの座標抽出

#5

投稿記事 by mo-fu » 12年前

みけCAT さんが書きました:また、出力の最初の整数と次の実数の間は全角スペースでないといけないのですか?
いいえ、どちらかといえばタブを挟むのがベストです。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: txt fileからの座標抽出

#6

投稿記事 by みけCAT » 12年前

mo-fu さんが書きました:言語ですが、使用言語はC言語なので出来ればCだとソースを読んだときに自分でも理解できるのでありがたいです。
C++が使えるのなら最近いいトピックがあったのですが、C言語ですね。
だとすると、bregexp.dllなどで正規表現を使用するか、自分で構文解析を行うことになると思います。
mo-fu さんが書きました:
みけCAT さんが書きました:また、出力の最初の整数と次の実数の間は全角スペースでないといけないのですか?
いいえ、どちらかといえばタブを挟むのがベストです。
でしたら、2番目(分割版)の

コード:

		print OUT "$4"." "."$1 $2 $3\n";
という行を、

コード:

		print OUT "$4\t$1 $2 $3\n";
としてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: txt fileからの座標抽出

#7

投稿記事 by みけCAT » 12年前

今回のデータの場合、対象の行にのみダブルクォーテーションマークが多いことを利用し、sscanfで読み込んでみました。

コード:

#include <stdio.h>
#include <string.h>

int countQuotation(const char* s) {
	int count=0;
	const char* now=s;
	for(count=0;now=strchr(now,'\"');now++)count++;
	return count;
}

int main(void) {
	char inputBuf[10240]={};
	int outputCounter=0;
	int outputFileCounter=0;
	const int outputFileLength=56;
	FILE* fp=NULL;
	while(fgets(inputBuf,sizeof(inputBuf),stdin)) {
		if(countQuotation(inputBuf)>=10) {
			char getData[4][1024]={};
			char* lastQuotation=strrchr(inputBuf,'\"');
			if(lastQuotation==NULL)continue;
			sscanf(inputBuf,"%*s%*s%s%s%s",getData[1],getData[2],getData[3]);
			sscanf(lastQuotation+1,"%s",getData[0]);
			if(outputCounter==0) {
				char fileName[1024]={};
				sprintf(fileName,"output%03d.txt",outputFileCounter);
				if(!(fp=fopen(fileName,"w"))) {
					fprintf(stderr,"Failed to open %s\n",fileName);
					return 1;
				}
			}
			fprintf(fp,"%s\t%s %s %s\n",getData[0],getData[1],getData[2],getData[3]);
			outputCounter++;
			if(outputCounter>=outputFileLength) {
				fclose(fp);
				outputCounter=0;
				outputFileCounter++;
			}
		}
	}
	if(outputCounter>0)fclose(fp);
	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

mo-fu

Re: txt fileからの座標抽出

#8

投稿記事 by mo-fu » 12年前

みけCAT様

休日出勤で返信が出来ず申し訳ありません。
やはり自分では思いつかないような点に着眼されるとともに、それをすばやく応用なさるのでとても勉強になります。

ほとんど丸投げ状態であるところにちからを貸してくださりありがとうございました。

これを基に色々と活用させていただきます!

閉鎖

“C言語何でも質問掲示板” へ戻る