Bash를 사용하여 열을 변경하고, 따옴표를 제거하고, 텍스트 파일에 탭을 추가하는 방법

Bash를 사용하여 열을 변경하고, 따옴표를 제거하고, 텍스트 파일에 탭을 추가하는 방법

나는 bash 스크립팅과 파일에 있는 텍스트에서 bash 및 awk를 처음 접했습니다.

"Index", "Year", "Age", "Name", "Movie"
1, 1928, 44, "Emil Jannings", "The Last Command, The Way of All Flesh" 
2, 1929, 41, "Warner Baxter", "In Old Arizona"
3, 1930, 62, "George Arliss", "Disraeli"
4, 1931, 53, "Lionel Barrymore", "A Free Soul"

이 출력을 얻고, 배우 이름으로 정렬하고, 제목 이름을 변경하고, 표를 포함하는 함수를 만들어야 합니다.

Actor               Year    Age   Film
Emil Jannings       1928    44    The Last Command, The Way of All Flesh
George Arliss       1930    62    Disraeli
Lionel Barrymore    1931    53    A Free Soul
Warner Baxter       1929    41    In Old Arizona

당신은 무엇을 할 것인가? 저는 아직 초보자이고 원하는 것을 얻을 수 있는 올바른 방법을 찾을 수 없습니다.

감사해요

답변1

csvcutPython 기반 csvkit 및 Miller 에서 :

$ csvcut -S -c Name,Year,Age,Movie file.csv | 
     mlr --icsv --opprint sort -f Name then rename Name,Actor,Movie,Film
Actor            Year Age Film
Emil Jannings    1928 44  The Last Command, The Way of All Flesh
George Arliss    1930 62  Disraeli
Lionel Barrymore 1931 53  A Free Soul
Warner Baxter    1929 41  In Old Arizona

Miller가 이 작업을 자체적으로 수행할 수 있어야 한다고 생각하지만 단일 문자가 아닌 경우 인용된 구분 기호를 잘못 구문 분석하는 것 같습니다.

답변2

FPAT에 GNU awk 사용:

$ cat tst.awk
BEGIN {
    in2outTag["Name"]  = "Actor"
    in2outTag["Movie"] = "Film"
    numOutFlds = split("Actor Year Age Film",outTags)
    FPAT = "\\s*(([^,]*)|(\"[^\"]+\"))\\s*"
    OFS = "\t"
}

{
    for (inFldNr=1; inFldNr<=NF; inFldNr++) {
        gsub(/^[[:space:]]*"?|"?[[:space:]]*$/,"",$inFldNr)
    }
}

NR == 1 {
    for (inFldNr=1; inFldNr<=NF; inFldNr++) {
        tag = ( $inFldNr in in2outTag ? in2outTag[$inFldNr] : $inFldNr )
        tag2inNr[tag] = inFldNr
    }

    printf "%d%s", 0, OFS
    for (outFldNr=1; outFldNr<=numOutFlds; outFldNr++) {
        tag = outTags[outFldNr]
        out2inNr[outFldNr] = tag2inNr[tag]
        printf "%s%s", tag, (outFldNr < numOutFlds ? OFS : ORS)
    }
    next
}

{
    printf "%d%s", 1, OFS
    for (outFldNr=1; outFldNr<=numOutFlds; outFldNr++) {
        inFldNr = out2inNr[outFldNr]
        val = $inFldNr
        printf "%s%s", val, (outFldNr < numOutFlds ? OFS : ORS)
    }
}

$ awk -f tst.awk file | sort -t$'\t' -k1,1n -k2,2 | cut -f2-
Actor   Year    Age     Film
Emil Jannings   1928    44      The Last Command, The Way of All Flesh
George Arliss   1930    62      Disraeli
Lionel Barrymore        1931    53      A Free Soul
Warner Baxter   1929    41      In Old Arizona

관련 정보