私は入力ファイルの最初のフィールドがファイル名であることを確認します。そうでない場合は、ファイル名を各行の最初の列として追加する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を使ってこれを行うことができますが、構文は最も簡単ではありません(または少なくとも私が考えることができる最善ではありません)。他のツールを使用する方が簡単で速いかもしれません。例えば、
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");
}