스크립트

스크립트

이것은 정보를 추출하려는 car_sales.txt 파일의 "작은" 부분입니다(전체 파일은 약 700줄이며 여기에 나열된 것보다 더 많은 차량 제조업체가 포함되어 있습니다).

first_name,last_name,price_paid,brand,year Mann,Mathers,20500.79,Chevy,2012 Doug,Samual,21000.12,Dodge,2015 Walter,Gray,17000.87,Dodge,2010 Jessica,Garnet,17350.00,MINI,2009 Paula,Raymond,45300.87,BMW,2015 Willie,Reynolds,64950.05,BMW,2015 Sam,Collins,70200.35,Lexus,2014 Katy,Martinez,29580.84,Chevy,2012 Nicole,Davis,31650.60,Chevy,2009 Brenda,Gray,12400.56,Dodge,2012 Samantha,Fernandez,27900.21,MINI,2015 Eric,Woods,68900.85,BMW,2009 George,Luke,33453.91,BMW,2011 Mildred,Takey,46820.80,Lexus,2012

"brand" 및 "price_paid" 열을 출력하고(그리고 모든 자동차에 대해 각 브랜드에 지불된 평균 가격을 찾고) 정렬(az)하고 첫 번째 행 "title"을 제거하려고 합니다. 이것은 내가 찾고 있는 결과입니다(위에 나열된 예에서).

BMW,53151.4 Chevy,27244.1 Dodge,16800.5 Lexus,58510.6 MINI,22625.1

나는 운 없이 이 문제를 해결하려고 이틀을 보냈고(나는 이 문제를 처음 접했습니다) 내가 생각할 수 있는 최선은 다음과 같습니다.

sed '1d' car_sales.txt |awk -F ',' '/Chevy/{print $3}' $1|awk '{total += $1; count ++}END{print "Chevy," total/count}'

분명히 이것은 내가 찾고 있는 것이 "아닙니다". "하나의" 브랜드/지불된 가격의 평균 생산량만 필요하다면, 그렇습니다. 제가 찾고 있는 단일 "패턴"을 입력하기만 하면 됩니다. 그러면 평균 가격을 지불하겠습니다.

하지만 car_sales.txt 파일에서 모든 브랜드의 평균 가격을 캡처하여 출력할 수 있는 방법을 찾고 있습니다. 내가 나열한 섹션에 있는 5개 브랜드 외에도 더 많은 브랜드(약 50개 이상)가 있습니다.

나는 내가 소유하고 있는 세 권의 책을 읽고 온라인에서 몇 시간 동안 검색했지만 평생 동안 그 내용을 이해할 수 없습니다. 어쩌면 내가 올바른 곳을 찾고 있지도 않을지도 모릅니다. awk가 답이라고 생각했지만 너무 큽니다. 미리 도움을 주셔서 진심으로 감사드립니다.

그러다가 아이디어가 떠올랐고, 이를 수행할 수 있는 방법을 찾았다고 생각하여 이 스크립트를 작성하기 시작했습니다. 논리적으로 그것은 내 머릿속에서 작동하는 것 같습니다. 첫 번째 함수의 출력을 두 번째 함수의 출력으로 사용한다는 생각입니다. 아아, 이것도 작동하지 않습니다. 나는 올바른 길을 가고 있다고 생각했지만 그렇지 않았습니다.

#!/bin/bash

#This will output the car "brand"
function brand {
        sed '1d' $1| cut -d ',' -f 4 |sort|uniq 
}

#The output of function "brand", will be the pattern for function "average"
function average {
    awk -F ',' '/'"$names"'/{print $3}' $1|awk '{total += $1; count ++}END{print "'$names'" "," total/count}'

}

brand $1
names=$(brand)
average $1 $names

답변1

배열은 문자열로 인덱싱 되므로 awk한 배열을 사용하여 해당 브랜드의 현재까지 총 가격을 보관하고 다른 배열을 사용하여 해당 브랜드의 레코드 수를 보관할 수 있습니다.

awk"브랜드"는 필드 4이므로 다음과 같이 배열을 인덱싱할 수 있습니다.

total_price[$4] += $3        # accumulate total price for this brand
count[$4] += 1               # increment count of records for this brand

마지막으로 배열의 키를 반복하고 평균을 계산하면서 출력 형식을 지정합니다.

POSIX에는 awk정렬 기능이 포함되어 있지 않으므로 명령의 출력은 awk표준 Unix sort명령으로 파이프됩니다.

이것을 시도해 보십시오:

스크립트

#!/bin/sh

#first_name,last_name,price_paid,brand,year
#print for each brand, the average price paid

awk -F, '
    NR == 1 {
        next                        # skip header
    }
    {
        price_paid[$4] += $3        # accumulate total price for this brand       
        count[$4] += 1              # increment count of records for this brand
    }
    END {
        for (brand in price_paid) {
            printf "%s,%7.2f\n", brand, price_paid[brand] / count[brand]
        }
    }
' < "${1:?filename required}" | sort

의견/설명

  1. 명령 을 호출하고 awk필드 구분 기호를 쉼표( ,)로 설정하고 스크립트에 표시된 대로 이 줄의 작은따옴표와 몇 줄 아래의 다음 작은따옴표 사이의 모든 내용을 전달합니다.

    awk -F, '
    
  2. 헤더 건너뛰기: 현재 레코드 번호가 1이면 현재 줄(첫 번째 줄)의 모든 처리를 건너뛰고 다음 입력 줄을 가져옵니다.

        NR == 1 {
            next                        # skip header
        }
    
  3. 브랜드별 총 가격을 누적합니다(각 행에서 수행됨). string으로 인덱스된
    배열 합계 . 브랜드 총 가격_지불 금액에 현재 지불 가격( )을 더합니다. 이 브랜드의 기록 수를 늘리십시오. price_paidcountbrand
    $3

        {
            price_paid[$4] += $3        # accumulate total price for this brand    
            count[$4] += 1              # increment count of records for this brand
        }
    
  4. 출력 테이블을 인쇄합니다. 모든 입력이 처리된 후 키( brand)를 단계별로 실행하여 price_paid배열에 도달하고 각 입력에 대한 합계의 평균을 brand인쇄합니다 .brandprice_paidbrand

        END {
            for (brand in price_paid) {
                printf "%s,%7.2f\n", brand, price_paid[brand] / count[brand]
            }
       }
    
  5. 스크립트 인수를 종료하고, filename 인수의 입력을 리디렉션하고, 명령의 출력을 명령 awk으로 파이프합니다.sort

    ' < "${1:?filename required}" | sort
    

작은따옴표( ')는 스크립트 매개변수를 종료합니다 awk. 첫 번째 명령줄 인수로 지정된 파일 이름
< "${1:?filename required}"의 표준 입력을 awk스크립트로 리디렉션합니다. 인수가 없으면 쉘은 "파일 이름 필요"가 포함된 오류 메시지를 인쇄하고 오류 상태로 종료됩니다.

관련 정보