Perlを使用してファイルの先頭に列を追加するには?

Perlを使用してファイルの先頭に列を追加するには?

私は入力ファイルの最初のフィールドがファイル名であることを確認します。そうでない場合は、ファイル名を各行の最初の列として追加するPerlの1行機能が必要です。

シェルで書かれた例:

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ライナーは他のシェルスクリプトの一部なので、小さな呼び出しがより良いようです(提案してください)。

答え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

1行も管理できませんが、ここに1行あります真珠スクリプト。ファイルに入れて実行可能にします。次に、*.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");
}

関連情報