쉘에 있는 두 출력의 데카르트 곱

쉘에 있는 두 출력의 데카르트 곱

주어진 파일에서 파일 이름과 열을 추출하는 쉘 스크립트가 있습니다. 디렉토리에서 읽어야 하는 예제 파일은 다음과 같습니다.

2222_AAA Accounting Statistic-42005_04May2020_0900-04May2020_1000.csv


#!/bin/bash

# Go to where the files are located
filedir=/home/vikrant_singh_rana/AAA_USP/sample-Files/*

for filename in $filedir
do
 #echo "Processing $filepath"
 # do something on $f
 printf '%s,%s\n' "$(basename "$filename" ".csv" | grep -oP '(?<=_).*(?=\-\d\d\d)' )" "$(head -n1 "$filename")"

done > test.txt;

위의 셸 스크립트는 다음과 같은 출력을 생성합니다. 입력 파일의 파일 이름 및 제목 열

cat test.txt
AAA Accounting Statistic,TIMESTAMP,C420050004,C420050005,C420050006,C420050007

파일 이름과 파일 열의 데카르트 곱을 기대합니다.

AAA Accounting Statistic,TIMESTAMP
AAA Accounting Statistic,C420050004
AAA Accounting Statistic,C420050005
AAA Accounting Statistic,C420050006
AAA Accounting Statistic,C420050007

답변1

첫 번째 행을 처리하려면 두 번째 루프가 필요합니다.$filename

for filename in /home/vikrant_singh_rana/AAA_USP/sample-Files/*; do
    # ...
    b=$(basename "$filename" ".csv" | grep -oP '(?<=_).*(?=\-\d\d\d)' )
    for c in $(head -n1 "$filename" | sed 's/,/ /g'); do
        printf '%s,%s\n' "$b" "$c"
    done
done > test.txt

추신: 첫 번째 줄에 공백 문자나 개행 문자가 없다고 가정합니다 $filename.

답변2

#!/bin/sh

for pathname in /home/vikrant_singh_rana/AAA_USP/sample-Files/*.csv
do
    name=${pathname##*/}   # remove directory path
    name=${name#*_}        # remove *_ prefix (up to first underscore)
    name=${name%%-*}       # remove -* suffix (from first dash)

    awk -F , -v name="$name" 'BEGIN { OFS=FS } { for (i = 1; i <= NF; ++i) print name, $i; exit }' "$pathname"
done

이는 모든 CSV 파일을 반복하여 NNNN_이름에서 디렉터리 경로와 초기 문자열은 물론 -첫 번째 문자 뒤의 모든 항목을 제거합니다. 문자열은 에 저장됩니다 $name.

awk그런 다음 파일의 첫 번째 줄에 있는 필드를 별도의 줄에 인쇄하는 짧은 프로그램을 실행합니다 . 각 줄에는 에서 추출한 값이 앞에 붙습니다 $name.

이는 CSV 파일이 다음과 같다고 가정합니다.단순한필드의 첫 번째 행에 쉼표나 줄바꿈이 포함되지 않은 CSV 파일입니다.


수천 개의 파일이 없다면 awk다음과 같이 GNU를 사용할 수도 있습니다.

awk -F , '
    BEGIN { OFS=FS }
    BEGINFILE {
        name = FILENAME
        sub(".*/", "", name)       # remove directory path
        sub("^[^_]*_", "", name)   # remove *_ prefix (up to first underscore)
        sub("-.*", "", name)       # remove -* suffix (from first dash)
    }
    {
        for (i = 1; i <= NF; ++i) print name, $i
        nextfile
    }' /home/vikrant_singh_rana/AAA_USP/sample-Files/*.csv

관련 정보