Perl을 사용하여 파일 시작 부분에 열을 추가하는 방법은 무엇입니까?

Perl을 사용하여 파일 시작 부분에 열을 추가하는 방법은 무엇입니까?

나는 입력 파일의 첫 번째 필드가 파일 이름인지 확인하고, 그렇지 않은 경우 파일 이름을 각 줄의 첫 번째 열로 추가하는 Perl 한 줄짜리 기능을 원합니다.

쉘로 작성된 예:

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

한 줄도 관리할 수 없지만 여기 한 줄이 있습니다진주스크립트. 파일에 넣어서 실행 가능하게 만드세요. 그런 다음 *.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");
}

관련 정보