如果文件中的第一行与模式匹配,则删除它

发布于 2025-01-02 04:49:56 字数 826 浏览 3 评论 0原文

我想知道是否有一种有效的方法来删除文件中的第一行(如果它与指定模式匹配)。例如,我有一个包含以下形式数据的文件:

Date,Open,High,Low,Close,Volume,Adj.Volume
2012-01-27,42.38,42.95,42.27,42.68,2428000,42.68
2012-01-26,44.27,44.85,42.48,42.66,5785700,42.66
.
.
.

我想删除第一行,仅当它包含文本时(如第一行示例所示),如果它仅包含数字,则保持不变(如其余行所示)。这项任务非常简单,我通过应用以下代码来完成它,该代码将每一行写入 $newFile 只要它不包含 Date 模式:

while( <$origFile> )
    {
        chomp($_);
        print $newFile $_ unless ($_  =~ m/Date/g)
    }

正如我所提到的,这就完成了工作。然而,当已知文本只能出现在第一行时,读取整个文件中的每一行似乎是对资源的极大浪费。

有什么方法可以更有效地完成此任务吗?

注意:我已经在此处找到了一个几乎类似的问题,但由于我希望我的代码也可以在 Linux 和 Windows 上使用,因此使用 sed 在这里对我没有帮助。

提前致谢!

I wonder if there is an efficient way to delete the first line in a file if it matches a specified pattern. For example, I have a file with data of the following form:

Date,Open,High,Low,Close,Volume,Adj.Volume
2012-01-27,42.38,42.95,42.27,42.68,2428000,42.68
2012-01-26,44.27,44.85,42.48,42.66,5785700,42.66
.
.
.

I want to delete the first line, only if it contains the text (as shown in the example in the first line), and leave it unchanged if it contains only numbers(as in the rest of the lines). This task is quite easy and I've accomplished it by applying the following peace of code which writes each line to a $newFile as long as it does not include Date pattern:

while( <$origFile> )
    {
        chomp($_);
        print $newFile $_ unless ($_  =~ m/Date/g)
    }

So as I mentioned, that makes the job done. However it seems that it's a great waste of resources to read each line in a whole file when it is known that the text can appear only in the first line..

Is there any way to accomplish this task more efficiently?

NOTE: I already found an almost similar question here, but since I want my code to be available on Linux and Windows as well, using sed will not help me here.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤寂小茶 2025-01-09 04:49:56

$. 可用于确定是否正在处理文件的第一行。

perl -i.bak -ne'print if $. != 1 || !/^Date/;' file

然而,读取整个文件中的每一行似乎是对资源的极大浪费

除了文件末尾之外,不可能从任何地方删除。要从开头或中间删除,文件中后面的所有内容都需要移动,这意味着它必须既可读取又可写入。

如果第一行不匹配,您只能避免工作(什么都不做)。如果需要删除该行,则必须复制整个文件。

$. can be used to determine if are processing the first line of the file.

perl -i.bak -ne'print if $. != 1 || !/^Date/;' file

However it seems that it's a great waste of resources to read each line in a whole file

It's impossible to delete from anywhere but the end of a file. To delete from the start or middle, everything that follows in the file needs to be shifted, which means it must be both read and written.

You can only avoid work if the first line doesn't match (by doing nothing at all). If you need to remove the line, you must copy the whole file.

七堇年 2025-01-09 04:49:56

Tie::File 模块非常适合此目的。它非常高效,因为它执行块 IO 而不是一次读取一行,并且使程序编写起来非常简单。

use strict;
use warnings;

use Tie::File;

tie my @data, 'Tie::File', 'mydatafile' or die $!;
shift @data if $data[0] =~ /Date/;
untie @data;

The Tie::File module is ideal for this. It is very efficient as it does block IO instead of reading a line at a time, and it makes the program very simple to write.

use strict;
use warnings;

use Tie::File;

tie my @data, 'Tie::File', 'mydatafile' or die $!;
shift @data if $data[0] =~ /Date/;
untie @data;
薄荷梦 2025-01-09 04:49:56

仅在第一行进行测试,然后运行文件的其余部分而不检查:

if (defined( $_ = <$origFile> )) {
    if ( ! m/Date/o ) { print $newFile $_ }

    my $data;

    for (;;) {
        my $readRes = read($origFile, $data, 0x10000);

        if (!defined $readRes) { die "Can't read: $!" }

        if ($readRes == 0) { last }

        print $newFile $data;
    }
}

Only do the test on the first line, then just run through the rest of the file without checking:

if (defined( $_ = <$origFile> )) {
    if ( ! m/Date/o ) { print $newFile $_ }

    my $data;

    for (;;) {
        my $readRes = read($origFile, $data, 0x10000);

        if (!defined $readRes) { die "Can't read: $!" }

        if ($readRes == 0) { last }

        print $newFile $data;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文