Perl函数提取具有指定起始列和长度的数据

Perl函数提取具有指定起始列和长度的数据,perl,extract,Perl,Extract,我正在尝试编写一个代码,从文件a中提取数据,并仅将具有指定起点和终点的列数据粘贴到文件B中。到目前为止,我只能成功地将所有数据从a复制到B,但如果过滤掉列,我将一事无成。我试着研究splice和grep,但没有结果。没有Perl方面的经验。数据没有列标题。 示例:数据实际上有数千行长-无法将数据插入函数 1. AAA 565 u8y 221 2. ABC 454 9u8 352 3. ADH 115 i98 544 4. AKS 352 87y 454 5. GJS 154 i9k 141 我

我正在尝试编写一个代码,从文件a中提取数据,并仅将具有指定起点和终点的列数据粘贴到文件B中。到目前为止,我只能成功地将所有数据从a复制到B,但如果过滤掉列,我将一事无成。我试着研究splice和grep,但没有结果。没有Perl方面的经验。数据没有列标题。 示例:数据实际上有数千行长-无法将数据插入函数

1. AAA 565 u8y 221
2. ABC 454 9u8 352
3. ADH 115 i98 544
4. AKS 352 87y 454
5. GJS 154 i9k 141
我希望将第3列start:8 length:3的所有唯一值复制到文件B中。我尝试了中提供的解决方案,但没有成功

谢谢你的任何提示或帮助

 #!/usr/bin/perl
use strict;
use warnings;

#use Cwd qw(abs_path);

#my $dir = '/home/
#$dir = abd_path($dir);
my $filename = "filea.txt";
my $newfilename = "fileb.txt"; 

#Open file to read raw data
open (DATA1, "<$filename") or die "Couldn't open $filename: $!";

#Open new file to copy desired columns
open (DATA2, ">$newfilename") or die "Couldn't open $newfilename: $!";

#Copy data from original to new file

while (<DATA1>) {
    #DATA2=splice(DATA1, 0,5);
    print DATA2 $_;
    my @fifth_column = map{(split)[1]} split /\n/, $newfilename;    
}

如果我理解正确的话,您可以使用一个相当简单的脚本来实现这一点

use strict;
use warnings;

my %seen;
while (<DATA>) {
    my $str = substr($_, 8, 3);   # the string you seek
    unless ($seen{$str}++) {      # if it is not seen before
        print "$str\n";           # ...print it
    }
}

__DATA__
AAA 565 u8y 221
AAA 565 u8y 221
ABC 454 9u8 352
ADH 115 i98 544
AKS 352 87y 454
GJS 154 i9k 141
这里使用数据文件句柄进行演示。我还在数据中添加了一个副本以演示重复数据消除。如果更改为,您可以简单地使用如下脚本:

perl script.pl filea.txt > fileb.txt
请注意,这依赖于数据的固定宽度,这意味着如果字段没有对齐,输出将被破坏

还请注意,这只是一个简单的单行程序的完整版本,如:

perl -nlwe '$x=substr($_,8,3); print $x unless $seen{$x}++' filea.txt > fileb.txt

如果我理解正确的话,您可以使用一个相当简单的脚本来实现这一点

use strict;
use warnings;

my %seen;
while (<DATA>) {
    my $str = substr($_, 8, 3);   # the string you seek
    unless ($seen{$str}++) {      # if it is not seen before
        print "$str\n";           # ...print it
    }
}

__DATA__
AAA 565 u8y 221
AAA 565 u8y 221
ABC 454 9u8 352
ADH 115 i98 544
AKS 352 87y 454
GJS 154 i9k 141
这里使用数据文件句柄进行演示。我还在数据中添加了一个副本以演示重复数据消除。如果更改为,您可以简单地使用如下脚本:

perl script.pl filea.txt > fileb.txt
请注意,这依赖于数据的固定宽度,这意味着如果字段没有对齐,输出将被破坏

还请注意,这只是一个简单的单行程序的完整版本,如:

perl -nlwe '$x=substr($_,8,3); print $x unless $seen{$x}++' filea.txt > fileb.txt

请看一下以下Perl命令:

:这允许您将一行数据拆分为一个数组: 例如:

while ( my $line = <$input_fh> ) {
    my @items = split /\s+/, $line;   #Columns are separated by spaces or tabs
    my $third_column = $items[2];  #The column you want;
    blah...blah...blah;
}
%unique\u列哈希跟踪,以查看您以前是否在文件的第三列中看到过该数据。将每个单独的关键点设置为什么并不重要。但是,我建议将其设置为非零值或空白值,因为如果执行此操作:

if ( $unique_columns{$data} )
而不是

if ( exists $unique_columns{$data} )

只要$unique_columns{$data}的值不是零或空,您的程序仍然可以工作,否则将失败。

请查看以下Perl命令:

:这允许您将一行数据拆分为一个数组: 例如:

while ( my $line = <$input_fh> ) {
    my @items = split /\s+/, $line;   #Columns are separated by spaces or tabs
    my $third_column = $items[2];  #The column you want;
    blah...blah...blah;
}
%unique\u列哈希跟踪,以查看您以前是否在文件的第三列中看到过该数据。将每个单独的关键点设置为什么并不重要。但是,我建议将其设置为非零值或空白值,因为如果执行此操作:

if ( $unique_columns{$data} )
而不是

if ( exists $unique_columns{$data} )

只要$unique_columns{$data}的值不为零或为空,您的程序仍能工作,否则将失败。

说到固定长度,没有什么比打包/解包更好的了,学习本教程,它将使您的生活更轻松,这项工作也将轻而易举


当谈到固定长度时,没有什么比打包/解包更好的了,学习本教程,它将使你的生活更轻松,这项工作轻而易举


一个班轮工作得很好!非常感谢你告诉我这个选择!它确实发出了下面的警告——尽管它给出了正确的输出@TLP名称main::只使用过一次:可能在-e行1处输入错误。意在添加-我对警告不太担心…仅供参考@TLP@todayspresent这一警告与此无关。它的存在仅仅是因为我们实际上一次做了两件事,除非$seen{$x}++是除非$seen{$x}的缩写$见{$x}++;。加上一行程序不使用strict,所以我们不声明变量。如果你觉得你的问题已经得到了回答,你可以点击旁边的复选标记来接受答案。谢谢!大多数情况下,答案是肯定的@TLP在使用代码时,它包含一些不应该包含的值。例如,在上面的输出中-如果我想省略前面带有“I”的那些。有没有一种方法可以让除非$seen{$x}++也使用除非substr$\u0,1ne'I'?如果我需要输入其他问题,请告诉我。谢谢@今天好吧,如果你能做到的话/^我/&$看到了{${}++假设我得到了所有的否定,但是你明白了。一行代码很好用!非常感谢你告诉我这个选择!它确实发出了下面的警告——尽管它给出了正确的输出@TLP名称main::只使用过一次:可能在-e行1处输入错误。意在添加-我对警告不太担心…仅供参考@TLP@todayspresent这一警告与此无关。它的存在仅仅是因为我们实际上一次做了两件事,除非$seen{$x}++是除非$seen{$x}的缩写$见{$x}++;。加上一行程序不使用strict,所以我们不声明变量。如果你觉得你的问题已经得到了回答,你可以点击旁边的复选标记来接受答案。谢谢!
大多数情况下,答案是肯定的@TLP在使用代码时,它包含一些不应该包含的值。例如,在上面的输出中-如果我想省略前面带有“I”的那些。有没有一种方法可以让除非$seen{$x}++也使用除非substr$\u0,1ne'I'?如果我需要输入其他问题,请告诉我。谢谢@今天好吧,如果你能做到的话/^我/&$看到了{${}++假设我得到了所有的否定,但是你明白了。这非常有用-我将不得不研究用什么行来替换blahs和yaddas-谢谢你的解释!:-@David W.yaddas将是:打印数据2$第三列@今天我更新了我的答案,展示了整个程序。啊,明白了!谢谢@David W.这非常有帮助-我将不得不研究使用什么行来替换blahs和yaddas-感谢您的解释!:-@David W.yaddas将是:打印数据2$第三列@今天我更新了我的答案,展示了整个程序。啊,明白了!谢谢@David W.模板A4*应该解压字符串。模板A4*应该解压字符串。