2

一个愚蠢的问题,但它让我疯狂!我有一个脚本可以删除 bvh 文件中的“胖”数据。(Biovision 动作捕捉文件..)。工作正常,但它创建了一个双扩展名......(名称.bvh.bvh)我只需要一个扩展名(*.bvh,而不是*.bvh.bvh !!!)这是代码:

@files = <*.bvh>;
foreach $file (@files) {
        open  (OLD, $file) || die "Couldn´t open $file: $!\n";
        open  (NEW, ">$file.bvh") || die "Couldn´t open $file.bvh: $!\n";
            while (<OLD>) {
                $line = $_;
                if (/Normal/) { while (<OLD>) { last if /}/; } $line => ""; }
                if (/normalIndex/) { while(<OLD>) { last if /[]]/; } $line = ""; }
                $line  =~  s/[-+]?[0-9]\.[0-9]+e[+-][0-9]+/0/g;
                $line  =~  s/([-+]?[0-9]+\.[0-9]{2})[0-9]+/$1/g;
                $line =~ s/0\.00/0/g;
                $line =~ s/[ ]+/ /g;
                $line =~ s/[\t]+/ /g;
                $line =~ s/^ //g;
                print NEW $line;

            }
            close OLD;
            unlink ($file);
            close NEW;          
            }

有什么帮助吗?谢谢!

4

3 回答 3

4
@files = <*.bvh>;

这为您提供了具有.bvh扩展名的文件的列表。所以它最终会包含如下内容:

('foo.bvh', 'bar.bvh', 'baz.bvh')

然后使用以下代码遍历数组:

foreach $file (@files) {
  ...
}

每次循环此循环,$file都将包含数组中的一个值。例如,第一次迭代$file将包含foo.bvh.

然后打开输入和输出文件:

open  (OLD, $file) || die "Couldn´t open $file: $!\n";
open  (NEW, ">$file.bvh") || die "Couldn´t open $file.bvh: $!\n";

$filecontains一样foo.bvh,您的新文件(使用名称创建"$file.bvh")将被调用foo.bvh.bvh

天真的解决方法是.bvhopen()语句中删除:

# DON'T DO THIS
open  (OLD, $file) || die "Couldn´t open $file: $!\n";
open  (NEW, ">$file") || die "Couldn´t open $file.bvh: $!\n";

这将不起作用,因为您的旧文件和新文件现在将具有相同的名称,并且当您打开新文件进行写入时,它将截断文件并删除所有输入数据。

您需要在某个时候重命名文件。最简单的方法是保留现有文件名,处理完每个文件后,将其重命名为原始名称。

# And then at the end of your loop
# Note that as you're copying the new file over the old one,
# there's no need to delete the old one.
close OLD;
close NEW;
rename("$file.bvh", $file);
于 2020-06-17T10:49:40.497 回答
2

只需插入rename("$file.new", $file);

如您的代码所示:

@files = <*.bvh>;
foreach $file (@files) {
        open  (OLD, $file) || die "Couldn´t open $file: $!\n";
        open  (NEW, ">$file.new") || die "Couldn´t open $file.new: $!\n";
            while (<OLD>) {
                $line = $_;
                if (/Normal/) { while (<OLD>) { last if /}/; } $line => ""; }
                if (/normalIndex/) { while(<OLD>) { last if /[]]/; } $line = ""; }
                $line  =~  s/[-+]?[0-9]\.[0-9]+e[+-][0-9]+/0/g;
                $line  =~  s/([-+]?[0-9]+\.[0-9]{2})[0-9]+/$1/g;
                $line =~ s/0\.00/0/g;
                $line =~ s/[ ]+/ /g;
                $line =~ s/[\t]+/ /g;
                $line =~ s/^ //g;
                print NEW $line;

            }
            close OLD;
            unlink ($file);

            close NEW;          
            rename("$file.new", $file);
            }
于 2020-06-17T13:05:03.693 回答
0

我相信这不是你可以获得输出的方式。

使用此模块重命名函数

use File::Copy;

@files = qw(first.bhv second.bhv third.bhv);
foreach $file (@files) {

只需删除extension原始文件上的

    (my $rem_ext = $file)=~s/\.bhv$//; 

重命名文件而不extension

    rename($file, $rem_ext);

只需阅读无extension文件

    open  (OLD, $rem_ext) || die "Couldn´t open $rem_ext: $!\n";

    open  (NEW, ">$file") || die "Couldn´t open $file.bvh: $!\n";
        while (<OLD>) {
             ...
        }
        close OLD;

删除我们自己extension创建的文件。

        unlink($rem_ext);
        close NEW;          
        }

它会起作用

于 2020-06-17T08:20:44.830 回答