如何使用 perl 在文件开头添加列?

如何使用 perl 在文件开头添加列?

我想要一个 Perl 单行代码来检查输入文件的第一个字段是否是文件名,如果不是,则将文件名添加为每行的第一列。

shell 中编写的示例:

for f in *file*.csv;
do 
  file_column=`cat ${f} | awk -F',' '{print$1}'`
  if [ $file_column != ${f} ]
  then
    sed -i "s/^/$f,/" $f 2>/dev/null;
  fi 
done

但上述方法检查文件名是否存在于第一列中,如果不存在则添加它,对于 4 Laks 文件大约需要 3 小时。我知道 Perl 对于文件操作更快。

我尝试过的 Perl 命令:

perl -p -i -e 's/^/Welcome to Hell,/' file*.csv

请帮助我添加逻辑来检查该字段是否已存在,并且仅在不存在时才进行更改。

Input : file1.csv 
col1,col2,col3 
data1,data2,dat3 

Output: file1.csv 
file1.csv,col1,col2,col3 
file1.csv,data1,data2,data3

或者如果这里有任何更快的方法请建议。 Perl 一个衬垫,因为它是另一个 shell 脚本的一部分,所以我想小调用会更好(请建议)

答案1

这是你的 perl 一行:它适用于多个文件参数

perl -i -pe '/^$ARGV,/ or print "$ARGV,"' file1 file2 ...

$ARGV是保存当前文件文件名的魔法变量。
请参阅http://perldoc.perl.org/perlvar.html#Variables-lated-to-filehandles

字段分隔符(逗号)是硬编码的。您可以决定这是否有问题。

小的性能改进:

perl -i -pe 'index($_, "$ARGV,") == 0 or print "$ARGV,"' file1 file2 ...

答案2

在讲述 perl 速度之前尝试加速你自己的脚本

for f in *file*.csv;
do 
    sed -i "/^$f,/! s/^/$f,/" "$f"
done

答案3

虽然您实际上可以使用 Perl 做到这一点,但语法并不是最简单的(或者至少,它不是我能想到的最好的)。使用其他工具可能会更简单、更快。例如,

  1. sed

  2. gawk(相对较新的版本)

    for f in file*csv; do  
        awk -i inplace -F, '{
                              if($1==FILENAME){print} else{print FILENAME","$0}
                            }' "$f"; 
    done
    

答案4

无法管理单行,但这里有一个珀尔脚本。将其放入文件中并使其可执行。然后将*.csv文件名作为参数指定给它。它创建*.new文件。如果您确信它有效,请取消注释 rename最后的命令。

#!/usr/bin/perl
use strict;
foreach my $file(@ARGV){
    open(F,$file) or die "$file:$!";
    $_ = <F>;
    next if $_=~/^$file,/;
    open(OUT,">$file.new") or die;
    my $add = "$file,";
    print OUT $add,$_;
    while(<F>){
        print OUT $add,$_;
    }
    close OUT;
    close F;
    #rename("$file.new","$file");
}

相关内容