我有一个非常大的文件,想要拉出所有原子符号和平衡几何的坐标。所需信息显示如下:
***** EQUILIBRIUM GEOMETRY LOCATED *****
COORDINATES OF ALL ATOMS ARE (ANGS)
ATOM CHARGE X Y Z
-----------------------------------------------------------
C 6.0 0.8438492825 -2.0554543742 0.8601734285
C 6.0 1.7887997955 -1.2651150894 0.4121141006
N 7.0 1.3006136046 0.0934593194 0.2602148346
注意:坐标完成后会出现一个空行。
到目前为止,我已修补了一段对我有意义的代码,但是它会产生错误,我不确定原因。 它在调用脚本后需要一个文件,当它看到包含EQUILIBRIUM GEOMETRY的字符串触发记录符号和坐标时,保存每一行并更改为$ start == 1。它继续保存包含坐标格式的行,直到它看到一个空白行,完成记录到$ geom。
#!/usr/bin/perl
$num_args = $#ARGV + 1;
if ($num_args != 1) {
print "\nMust supply GAMESS .log file.\n";
exit;
}
$file = $ARGV[0];
open FILE, "<", $file;
$start = 0;
$geom="";
while (<FILE>) {
$line = $_;
if ( $line eq "\n" && ($start == 1) ) {
$start = 0; }
if ( $start == 1 && $line =~ m/\s+[A-Z]+\s+[0-9\.]+\s+[0-9\.\-]+\s+[0-9\.\-]+\s+[0-9\.\-]+/ ) {
$line =~ s/^\s+//;
@coordinates = split(/\s+/,$line);
$geom=$coordinates[0],$coordinates[3],$coordinates[4],$coordinates[5];
}
if ( $line =~ m/\s+\*+ EQUILIBRIUM GEOMETRY LOCATED\s\*+\s+) {
$geom = "";
$start = 1;
}
}
print $geom;
错误讯息:
Unrecognized character \xC2; marked by <-- HERE after <-- HERE near column 1 at ./perl-grep line 5.
答案 0 :(得分:1)
第13行有一个不可见的字符
我创建了一个只包含此行的文件(通过剪切/粘贴) 然后在上面添加一行是我的重新输入
$的geom =&#34;&#34 ;;
$的geom =&#34;&#34 ;;
看起来相同但不是(第二行是有缺陷的)
[tmp]=> cat x | perl -ne '$LINE = $_; $HEX = unpack "H*"; print "$HEX $LINE" '
2467656f6d3d22223b0a $geom="";
2467656f6d3d22223be280a80a $geom="";
当您对文件进行六分法时,可以看到还有一些字符。 所以=&gt;只需完全删除这一行并重新输入
顺便提一下,您的文件中还有另一个问题,您错过了关闭正则表达式&#39; /&#39;
if ( $line =~ m/\s+\*+ EQUILIBRIUM GEOMETRY LOCATED\s\*+\s+) {
但我想,完成你的剧本还有很多工作要做,因为我没有看到太多的目的;)
答案 1 :(得分:0)
我把它复制到我的Linux盒子里并遇到了同样的问题。
基本上,该剧本说该行中有一个不可读的角色:
$geom="";
我在gedit中重新键入了该行并运行了文件。
此外,脚本底部还有一个未封闭的正则表达式。我添加一个&#34; /&#34;到以下行:
if ( $line =~ m/\s+\*+ EQUILIBRIUM GEOMETRY LOCATED\s\*+\s+) {
答案 2 :(得分:0)
好的,首先 - strict
和warnings
真的是当你写一个scirpt并遇到问题时的第一个停靠点。实际上,即使在你遇到问题之前 - 打开它们并坚持它们。*
与你的代码一样:
$geom="";?
- 尾随问号。应该删除。$num_args = $#ARGV + 1;
- 多余的。 scalar @ARGV
具有相同的结果。 open FILE, "<", $file;
- 3 arg open是好的。不使用词法文件句柄或检查成功是不好的。 $line = $_;
- 多余的。只需使用while ( my $line = <FH> ) {
代替。 if ( $line =~ m/\s+\*+ EQUILIBRIUM GEOMETRY LOCATED\s\*+\s+)
- 破坏的正则表达式,没有尾随/
。 $geom=$coordinates[0],$coordinates[3],$coordinates[4],$coordinates[5];
- 没有做你的想法。您可能希望join
这些或连接它们。 $line eq "\n"
- 选择空行,但如果您chomp;
优先eq ''
,可能会更好。 $start
看起来您正在尝试与range
运营商做同样的事情。 http://perldoc.perl.org/perlop.html#Range-Operators $geom
。这是你的意图吗? $line =~ s/^\s+//;
- 如果您所做的只是split
,则是多余的。 split ' '
做同样的事情。 close
文件句柄的良好形式。特别是当它没有词汇范围时。 因此,考虑到这一点,您的代码可能看起来像这样:
#!/usr/bin/perl
use strict;
use warnings;
if ( @ARGV != 1 and not -f $ARGV[0] ) {
print "\nMust supply GAMESS .log file.\n";
exit;
}
open( my $input_fh, "<", $ARGV[0] ) or die $!;
my $geom = "";
while ( my $line = <$input_fh> ) {
chomp $line;
if ( $line =~ m/\s+\*+ EQUILIBRIUM GEOMETRY LOCATED\s\*+\s+/ .. m/^$/ ) {
if ( $line
=~ m/\s+[A-Z]+\s+[0-9\.]+\s+[0-9\.\-]+\s+[0-9\.\-]+\s+[0-9\.\-]+/
)
{
my @coordinates = split( ' ', $line );
$geom = join( "",
$coordinates[0], $coordinates[3],
$coordinates[4], $coordinates[5] );
}
}
}
close($input_fh);
print $geom;
(如果你有一些样本输入,我会验证它)。
*有时您可能想要关闭它们。如果您知道这些是什么以及为什么,那么您将其关闭。否则只是假设他们是强制性的。