Shell – How to add column in the beginning of file using perl

awkperlsedshell

I want a Perl one-liner that checks whether the first fields of an input file is the file's name and, if it isn't, adds the file name as the first column on every line.

Example written in 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

But the approach above, which checks whether the file name is present in the first column and adds it if it isn't, is taking ~3 Hours for 4 Laks files. I understand that Perl is faster for file operations.

The Perl command I tried:

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

Please help me add the logic to check whether the field exists already and only change if it doesn't.

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

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

or if here is any faster way please suggest. Perl one liner because it's part of another shell script so tiny call will be better i guess (suggest please)

Best Answer

Here's your perl one-liner: it works with multiple file arguments

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

$ARGV is the magic variable that holds the filename of the current file.
See http://perldoc.perl.org/perlvar.html#Variables-related-to-filehandles

The field separator (comma) is hardcoded. You can decide if that's a problem.

Small performance improvement:

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