폴더의 모든 csv 파일에 대한 데이터 행 끝에 헤더 필드와 파일 이름을 추가합니다.

폴더의 모든 csv 파일에 대한 데이터 행 끝에 헤더 필드와 파일 이름을 추가합니다.

폴더에 있는 모든 csv 파일의 모든 줄 끝에 파일 이름(확장자 없음)을 추가하고 싶습니다. 모든 파일에는 동일한 헤더가 있습니다.

내 폴더에 a.csv와 b.csv라는 두 개의 파일이 있다고 가정해 보겠습니다.

a.csv에는 다음이 포함됩니다(첫 번째 행은 헤더임).

num1,num2,num3  
1,2,3

b.csv에는 다음이 포함됩니다(첫 번째 행은 헤더임).

num1,num2,num3    
4,5,6

.csv 파일을 원합니다(첫 번째 행이 헤더임).

num1,num2,num3,filename  
1,2,3,a

b.csv 파일을 원합니다. (첫 번째 행은 헤더입니다.)

num1,num2,num3,filename  
4,5,6,b

유닉스에서는 어떻게 할 수 있나요?

답변1

for file in *.csv
do
  filename=${file%.csv}
  sed -i -e "1s/\$/,filename/; 2,\$s/\$/,$filename/" "$file"
done
  1. *csv현재 디렉토리의 각 파일을 반복합니다 .
  2. 후행을 제거하여 파일 이름 텍스트 준비.csv
  3. -ised를 사용하여 파일을 제자리에서 편집하세요.
    1. 1번째 줄에서만 줄 끝을 검색하여 text (escaped $) 로 바꿉니다 ,filename.
    2. 2번째 줄부터 파일 끝( $)까지, 줄 끝( $)을 검색하여 쉼표와 준비된 파일 이름으로 바꿉니다.

답변2

OP를 올바르게 이해한다면 "이상적인"솔루션은 다음을 사용하는 것입니다 (확장자가 없는 라인 1, 확장자가 있는 나머지 라인) GNU awk.

gawk -F, -i inplace \
'BEGIN {
    OFS=",";
 }
 {
    if(FNR==1)
        name = gensub(/^(.*)\..*/, "\\1", "g", FILENAME);
    else
        name = FILENAME;

    print $0, name;
 }' *.csv

, 핸들 -F및 할당은 OFS=","입력 및 출력 필드 구분 기호를 로 설정합니다 ,.

-i inplace파일의 현재 레코드를 자르고 현재 출력을 파일에 쓰는 것을 의미합니다.

gensub 내장은 확장자 없이 파일 이름을 저장하고 print 문은 필요한 수정 기록을 인쇄합니다.

답변3

다음 명령을 사용하십시오밀러( mlr)는 CSV 파일을 읽고 filename현재 파일의 경로 이름(명령줄에 제공됨)을 포함하고 .csv끝에서 제거하는 새 필드를 각 파일에 추가합니다.

mlr -I --csv put '$filename = sub(FILENAME,"\.csv$","")' a.csv b.csv

를 사용하면 -I현재 위치에서 파일을 변경할 수 있으며 각 파일은 개별적으로 처리됩니다. 나머지는 익숙해야 하며 awk보너스는 이름으로 필드를 참조할 수 있다는 것입니다. 새 필드 이름을 할당하면 필드가 생성됩니다.

Miller는 인용이 필요한 모든 필드를 자동으로 인용합니다.

$ cat a.csv
num1,num2,num3
1,2,3
$ cat b.csv
num1,num2,num3
4,5,6
$ mlr -I --csv put '$filename = sub(FILENAME,"\.csv$","")' a.csv b.csv
$ cat a.csv
num1,num2,num3,filename
1,2,3,a
$ cat b.csv
num1,num2,num3,filename
4,5,6,b

관련 정보