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
같지만 다른 것입니다.outputdirday
outputdir
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"
(따옴표 안의) 의미는끈o
u
t
d
i
r
, 대신에값변수를outdir
수행해야 합니다.파일 이름 = outdir "/Customer_Create_Records.dat"
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
거의 중요한 것:
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
- 타당한 이유가 없고 수행 중인 작업을 확실히 알고 있지 않는 한 항상 쉘 변수 참조(예:
"$outputdirday"
,"$inputdir"
및 )를 인용해야 합니다."$sourcefile"
이것이 문제의 원인은 아닌 것 같지만 결국에는 문제를 일으킬 것입니다. - 명확성을 위해 다음
`…`
으로 변경하고 싶을 수도 있습니다 .$(…)
이것,이것, 그리고이것.
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
- 타당한 이유가 없는 한 항상 쉘 변수 참조를 인용해야 하지만 이는 백슬래시에는 적용되지 않습니다. 정당한 경우에만 사용해야 합니다. 예를 들어
date +%Y%m%d
등date +%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