awk 내에서 입력 필드 값에 따라 다른 디렉터리에 새 파일을 생성합니다.

awk 내에서 입력 필드 값에 따라 다른 디렉터리에 새 파일을 생성합니다.

awk를 사용하려고하는데

    datetime=`date +\%Y\%m\%d`
    logdatetime=`date +\%Y\%m\%d`
    foldermonth=`date +\%B_\%Y`
    folderday=`date +\%d`
    inputdir="~/sboper/Standalone/fsplit/GLMS"
    outputdir="~/sboper/StandAlone/input/$foldermonth"
  outputdirday="~/sboper/StandAlone/input/$foldermonth/GLMS_Daily/$folderday"

    awk -v outdir=$outputdirday 'BEGIN{ FS = "~" } ;{if( $12 == "A" ) filename="outdir/Customer_Create_Records.dat" ; print >> filename;close(filename)}' $inputdir/$sourcefile

    awk -v outdir=$outputdirday 'BEGIN{ FS = "~" } ;{if( $12 == "M" ) filename="outdir/Customer_Modify_Records.dat" ; print >> filename;close(filename)}' $inputdir/$sourcefile

그러나 변수는 outdir=$outputdirday내 출력 디렉터리 경로의 값으로 확장되지 않습니다.

awk 변수를 선언했지만 awk 스크립트에서 쉘 변수를 사용하지 않았습니다. 하지만 여전히 오류가 발생합니다 cannot open Customer_Create_Records.dat.

내 스크립트에 무슨 문제가 있나요? "outdir" 대신 전체 경로를 복사하면 새 파일이 생성되고 레코드가 이동되지만 변수에 사용될 때 제대로 작동하지 않습니다. awk를 통해 원하는 디렉토리에 새 파일을 어떻게 만들 수 있나요?

답변1

우와. 어디서부터 시작해야 하나요?

  • 디버깅하는 방법을 배워야 합니다.  Bash 스크립트를 디버깅하는 방법은 무엇입니까? 이 주제에 대한 높은 평가를 받은 Stack Exchange 참고 자료로, 가장 많은 활동을 하는 회원 중 일부가 기여했습니다. 이 사이트에서 추가 정보를 찾을 수 있으며 웹에서도 더 많은 정보를 찾을 수 있습니다. 예를 들어,
    • 단순화하다.
      • folderday, 할당을 제거 foldermonth 하고 상수 값으로 구성하세요.`date …`outputdirday
      • 혼란스러울 정도로 유사한 변수 이름을 피하십시오. 예를 들어 와 outdir같지만 다른 것입니다.outputdirdayoutputdir
      • datetime사용하지 않는 , logdatetime및 스크립트도 제거하세요 .outputdir
      • 중복을 제거합니다. 표시되는 두 명령은 awk사소한 차이점을 제외하면 동일합니다. 그 중 하나는 작동하고 하나는 실패합니까? 그들은 다른 방식으로 실패할 것인가? 난 그렇게 생각하지 않아. 그럼 둘 다 보지 못하게 해주세요.
      • 실제로 사용하지 않는 한 긴 8단계 경로 이름(예: ~/sboper/StandAlone/input/$foldermonth/GLMS_Daily/$folderday/Customer_Create_Records.dat) 을 사용하지 마십시오.진짜필요.
    • 시연 목적으로(즉, 다른 사람에게 문제를 시연할 때) 출력 디렉터리 이름 지정과 같은 혼동되는 명명 규칙을 피하십시오 …/input/….
    • 프레젠테이션 목적으로 화면보다 넓은 줄을 사용하지 마십시오. 따라서 전체 내용을 읽으려면 스크롤해야 합니다. 대부분의 시스템에는 명령과 프로그램을 여러 줄로 나눌 수 있는 방법이 있습니다.
    • 디렉토리에 실제로 두 개의 디렉토리(하나는 호출됨, 다른 하나는 호출됨)가 있습니까 Standalone?StandAlone~/sboper
    • 최종 결과가 원하는 결과가 아닌 경우 프로세스 중간에 무슨 일이 일어났는지 알아보세요. 중간값을 표시합니다. 예를 들어,
      • outputdirday. 스크립트를 실행하고 echo "$outputdirday"이전에 실행 하면 awk다음과 같은 결과가 나타납니다.
        ~/sboper/StandAlone/input/June_2016/GLMS_Daily/08
        즉, ~따옴표로 묶여 있기 때문에 내 홈 디렉터리로 확장되지 않습니다. 과제를 다음으로 변경해야 했어요
        outputdirday="$HOME/sboper/StandAlone/input/$foldermonth/GLMS_Daily/$folderday"
        작동하게 만들다.
      • outdir. 제대로 설정되지 않았다고 하는데, 인쇄해 보셨나요? 이렇게 하면 내가 얻은 것과 동일한 값을 얻습니다 outputdirday.
      • filename.  이것문제(부분)는 아래를 참조하세요.
  • 도움을 요청할 때 해야 할 일
    • 위에서 언급했듯이 문제를 단순화합니다.
    • 명령이 수행해야 하는 작업을 설명하세요.
    • 입력 파일의 모양을 보여줍니다.
    • 예상되는 출력이 어떻게 보이는지 보여주세요.
    • 사용 중인 소프트웨어 버전을 확인합니다. 나는 귀하의 스크립트에 어떤 문제가 있는지 이해하고 있다고 생각하지만 귀하의 오류를 정확하게 재현할 수는 없습니다(따라서 다른 버전을 실행하고 있는 것 같습니다 awk). 아마진짜중요하지만 어떤 운영 체제를 사용하고 있는지도 밝히지 않았습니다.


이것은 중요한 부분입니다:

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

  • 위에서 제안한 대로 스크립트의 기본 작업 블록을 더 짧은 줄로 나누었다면 awk그 내용이 다음과 같다는 것을 깨달았을 것입니다.
    {
          if ( $12 == "A" )
                파일 이름="outdir/Customer_Create_Records.dat"
          인쇄 >> 파일 이름
          닫기(파일명)
    }
    ~처럼마이클 웰스에서 지적하다그의 대답, 이 그룹filename 가정 어구을 입력한 다음모든줄을 입력하세요filename 무조건. 그가 제안한 대로 다음과 같은 작업을 수행해야 합니다.
    {
          if($12=="A"){
                파일 이름="outdir/Customer_Create_Records.dat"
                인쇄 >> 파일 이름
                닫기(파일명)
          }
    }
  • filename위에서 제안한 대로 값을 설정한 후 인쇄하면 다음과 같은 값이 표시됩니다.
    outdir/Customer_Create_Records.dat
    왜냐하면 "outdir"(따옴표 안의) 의미는 outdir, 대신에변수를 outdir수행해야 합니다.
    파일 이름 = outdir "/Customer_Create_Records.dat"

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

거의 중요한 것:

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

  • 타당한 이유가 없고 수행 중인 작업을 확실히 알고 있지 않는 한 항상 쉘 변수 참조(예: "$outputdirday", "$inputdir"및 )를 인용해야 합니다. "$sourcefile"이것이 문제의 원인은 아닌 것 같지만 결국에는 문제를 일으킬 것입니다.
  • 명확성을 위해 다음 `…`으로 변경하고 싶을 수도 있습니다 .$(…)이것,이것, 그리고이것.

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

  • 타당한 이유가 없는 한 항상 쉘 변수 참조를 인용해야 하지만 이는 백슬래시에는 적용되지 않습니다. 정당한 경우에만 사용해야 합니다. 예를 들어 date +%Y%m%ddate +%B_%Y은 잘 작동합니다.
  • awk이전에 제안한 것처럼 수행 중인 작업에 대해 두 번 호출할 필요가 없습니다 . 당신은 모든 것을 달성 할 수 있습니다

    awk -v outdir="$outputdirday" '
        BEGIN { FS = "~"
                filenameA = outdir "/Customer_Create_Records.dat"
                filenameM = outdir "/Customer_Modify_Records.dat"
              }
              {
                if ($12 == "A") print >> filenameA
                if ($12 == "M") print >> filenameM
              }
        ' "$inputdir/$sourcefile"
    

    또는

    awk -v outdir="$outputdirday" '
        BEGIN { FS = "~"
                filenameA = outdir "/Customer_Create_Records.dat"
                filenameM = outdir "/Customer_Modify_Records.dat"
              }
        $12 == "A" { print >> filenameA}
        $12 == "M" { print >> filenameM}
        '    "$inputdir/$sourcefile"
    

    내가 아는 한, close이러한 파일은 전혀 필요하지 않습니다. 파일은 일반적으로 프로그램이 종료될 때 자동으로 닫힙니다.

답변2

귀하의 질문이 명확하지 않지만 다음을 원할 수도 있습니다.

if( $12 == "A" ) {
    filename="outdir/Customer_Create_Records.dat" ;
    print >> filename;close(filename)
}

중괄호가 없으면 조건문의 "then" 절은 첫 번째 세미콜론에서 끝나게 됩니다. 따라서 출력 파일의 이름을 정의하기 전에 출력 파일에 줄을 쓰려고 할 수 있습니다.

답변3

문제는 awk 구문과 awk에 제공하는 입력 파일에 있습니다. "$inputdir/$sourcefile" - 단일 파일 이름으로 확장되지 않습니다.

답변을 게시한 모든 분들께 감사드립니다. 오류를 이해하는 데 도움이 되었습니다. 생성된 코드는 다음과 같습니다(이것은 더 큰 스크립트의 조각이므로 내가 선언하는 모든 변수는 이 조각에만 관련되지 않을 수 있습니다).

    timestamp=`date +\%Y\%m\%d\%H\%M\%S`
    logfile=/udd001/sboper/CMStandAlone/input/logs/SBSA_GLMS_CUST_$timestamp.log
    datetime=`date +\%Y\%m\%d`
    logdatetime=`date +\%Y\%m\%d`
    foldermonth=`date +\%B_\%Y`
    folderday=`date +\%d`
    inputdir="/udd001/sboper/CMStandalone/fsplit/GLMS"
    outputdir="/udd001/sboper/CMStandAlone/input/$foldermonth"
    outputdirday="/udd001/sboper/CMStandAlone/input/$foldermonth/GLMS_Daily/$folderday"
    inputfile=$( ls -1 /udd001/sboper/CMStandalone/fsplit/GLMS/GCP1_cdf_001_$datetime*.txt )
    sourcefile=`basename $inputfile`

    if [ ! -d "$outputdirday" ]; then
            mkdir -p "$outputdirday"
            fi
                    if [ -f "$inputdir/$sourcefile" ]
                    then
                    cp "$inputdir/$sourcefile" "$outputdirday"

                    echo "output directory : $outputdirday"
                     awk -v outdir="$outputdirday" '
                        BEGIN { FS = "~"
                        filenameA = outdir"/SBSA_Amdocs_Customer_Create_Records.dat"
                        filenameM = outdir"/SBSA_Amdocs_Customer_Modify_Records.dat"
                        }
                        $12 == "A" { print >> filenameA}
                        $12 == "M" { print >> filenameM}
                        '    "$inputdir/$sourcefile

"

        fi        

관련 정보