如何修复 unix 中 Sed 命令中的错误文件描述符

How to fix Bad File descriptor in a Sed Command in unix

我有一个源文件,其中包含许多组编号(假设它是一个关键字段)和相关数据。我正在使用 awk 和 sed 命令根据在源文件中找到的组号创建单独的文件。

我正在做下面的事情。我的输出符合预期,但在 运行 命令时低于警告。

sed: couldn't close stdout: Bad file descriptor

代码:

awk -F, '{print  FSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFSFS>  }'
for i in *.csv; do
    sed -i -e  "1 i\RECORD_TYPE,GROUP_NO,ACCOUNT_NO,EMPLOYEE_SSN,CARS_ERROR_CODE,CARS_ERROR_DESC,NEW_PARTICIPANT_ID,DEPENDENT_SSN,EFFECTIVE_DATE,DEPENDENT_SEQ_NO,LAST_NAME,FIRST_NAME,MIDDLE_INITIAL,ADDRESS_LINE_1,ADDRESS_LINE_2,ADDRESS_LINE_3,CITY,STATE,ZIPCODE,RELATIONSHIP_CODE,DATE_OF_BIRTH,SEX_CODE,SMOKER_INDICATOR,HIRE_DATE,LOCATION_NO,LOCATION_DATE,REPORTED_SALARY,SALARY_MODE,SALARY_EFFECTIVE_DATE,WEEKLY_HOURS,PRODUCT_ID,TERMINATION_DATE,TERM_REASON_CODE,COVERAGE_OPTION,PLAN_CODE,UNITS,PRODUCT_SET_ID,UNDERWRITING_STATUS_IND,APPLICATION_RECEIVED_DATE,CERTIFICATE_NO,STATUS_TYPE,FILE_ID,FILE_DATE,CARS_DATE"  $i
done

为什么在创建新文件时不直接从 Awk 脚本打印 header?

awk -F, 'BEGIN { OFS=FS }
{ if (!a[]++)
    print "RECORD_TYPE", "GROUP_NO", "ACCOUNT_NO", "EMPLOYEE_SSN", \
     "CARS_ERROR_CODE", "CARS_ERROR_DESC", "NEW_PARTICIPANT_ID", \
     "DEPENDENT_SSN", "EFFECTIVE_DATE", "DEPENDENT_SEQ_NO", \
     "LAST_NAME", "FIRST_NAME", "MIDDLE_INITIAL", "ADDRESS_LINE_1", \
     "ADDRESS_LINE_2", "ADDRESS_LINE_3", "CITY", "STATE", "ZIPCODE", \
     "RELATIONSHIP_CODE", "DATE_OF_BIRTH", "SEX_CODE", "SMOKER_INDICATOR", \
     "HIRE_DATE", "LOCATION_NO", "LOCATION_DATE", "REPORTED_SALARY", \
     "SALARY_MODE", "SALARY_EFFECTIVE_DATE", "WEEKLY_HOURS", "PRODUCT_ID", \
     "TERMINATION_DATE", "TERM_REASON_CODE", "COVERAGE_OPTION", "PLAN_CODE", \
     "UNITS", "PRODUCT_SET_ID", "UNDERWRITING_STATUS_IND", \
     "APPLICATION_RECEIVED_DATE", "CERTIFICATE_NO", \
     "STATUS_TYPE", "FILE_ID", "FILE_DATE", "CARS_DATE" >
  print , , , , , , , , , , , , , \
    , , , , , , , , , , , \
    , , , , , , , , , , , , \
    , , , , , , , >  }'

也许还要注意 OFS=FS,这样您就可以使用简单的逗号代替 FS

使用 GNU awk 处理多个同时打开的输出文件:

awk '
    BEGIN {
        FS = OFS = ","
        for (i=8; i<=42; i++) fldNrs = fldNrs FS i
        nf = split("2,3,6,4,43,44,5" fldNrs ",45",out2in)
        split("RECORD_TYPE,GROUP_NO,ACCOUNT_NO,EMPLOYEE_SSN,CARS_ERROR_CODE,CARS_ERROR_DESC,NEW_PARTICIPANT_ID,DEPENDENT_SSN,EFFECTIVE_DATE,DEPENDENT_SEQ_NO,LAST_NAME,FIRST_NAME,MIDDLE_INITIAL,ADDRESS_LINE_1,ADDRESS_LINE_2,ADDRESS_LINE_3,CITY,STATE,ZIPCODE,RELATIONSHIP_CODE,DATE_OF_BIRTH,SEX_CODE,SMOKER_INDICATOR,HIRE_DATE,LOCATION_NO,LOCATION_DATE,REPORTED_SALARY,SALARY_MODE,SALARY_EFFECTIVE_DATE,WEEKLY_HOURS,PRODUCT_ID,TERMINATION_DATE,TERM_REASON_CODE,COVERAGE_OPTION,PLAN_CODE,UNITS,PRODUCT_SET_ID,UNDERWRITING_STATUS_IND,APPLICATION_RECEIVED_DATE,CERTIFICATE_NO,STATUS_TYPE,FILE_ID,FILE_DATE,CARS_DATE",outHdrs)
    }
    { out =  ".csv" }
    !seen[]++ {
        for ( i=1; i<=nf; i++ ) {
            printf "%s%s", outHdrs[i], (i<nf ? OFS : ORS) > out
        }
    }
    {
        for ( i=1; i<=nf; i++ ) {
            printf "%s%s", $(out2in[i]), (i<nf ? OFS : ORS) > out
        }
    }
' file

对于其他 awk,应用 DSU (Decorate/Sort/Undecorate) 算法会更加高效和稳健,例如使用任何 awk、排序和剪切:

awk 'BEGIN{FS=OFS=","} {print , NR, [=11=]}' file |
sort -t',' -k1,1 -k2,2n |
cut -d',' -f3- |
awk '
    BEGIN {
        FS = OFS = ","
        for (i=8; i<=42; i++) fldNrs = fldNrs FS i
        nf = split("2,3,6,4,43,44,5" fldNrs ",45",out2in)
        split("RECORD_TYPE,GROUP_NO,ACCOUNT_NO,EMPLOYEE_SSN,CARS_ERROR_CODE,CARS_ERROR_DESC,NEW_PARTICIPANT_ID,DEPENDENT_SSN,EFFECTIVE_DATE,DEPENDENT_SEQ_NO,LAST_NAME,FIRST_NAME,MIDDLE_INITIAL,ADDRESS_LINE_1,ADDRESS_LINE_2,ADDRESS_LINE_3,CITY,STATE,ZIPCODE,RELATIONSHIP_CODE,DATE_OF_BIRTH,SEX_CODE,SMOKER_INDICATOR,HIRE_DATE,LOCATION_NO,LOCATION_DATE,REPORTED_SALARY,SALARY_MODE,SALARY_EFFECTIVE_DATE,WEEKLY_HOURS,PRODUCT_ID,TERMINATION_DATE,TERM_REASON_CODE,COVERAGE_OPTION,PLAN_CODE,UNITS,PRODUCT_SET_ID,UNDERWRITING_STATUS_IND,APPLICATION_RECEIVED_DATE,CERTIFICATE_NO,STATUS_TYPE,FILE_ID,FILE_DATE,CARS_DATE",outHdrs)
    }
     != prev {
        close(out)
        out =  ".csv"
        for ( i=1; i<=nf; i++ ) {
            printf "%s%s", outHdrs[i], (i<nf ? OFS : ORS) > out
        }
        prev = 
    }
    {
        for ( i=1; i<=nf; i++ ) {
            printf "%s%s", $(out2in[i]), (i<nf ? OFS : ORS) > out
        }
    }
'

有关 DSU 的更多信息,请参阅