DATA
특정 키워드( , ) 사이에 여러 개의 데이터 덩어리가 포함된 데이터 파일이 있습니다 END
. 나는 이것을 사용하여 awk
해당 청크에서 얻은 파일 이름을 기반으로 데이터 청크를 별도의 파일로 추출합니다. 일부 데이터 덩어리는 동일한 이름을 공유하므로 blockname
파일(" ")이 이미 존재하는 경우 증분 정수를 사용하여 각 출력 파일의 이름을 바꿉니다.
#cat input.file
useless stuff1
DATA blockname1
data1
data1
END
useless stuff2
DATA blockname2
data2
data2
END
useless stuff3
DATA blockname1
data3
data3
END
useless stuff4
3개의 출력 파일 이 예상됩니다 blockname1
. (마지막 파일에 정수가 어떻게 할당되는지 확인하세요.)blockname2
blockname1_1
#cat blockname1
DATA blockname1
data1
data1
END
(다른 사람들도 그에 따라...)
이제 다음 스크립트는 내가 원하는 방식으로 작동합니다.
awk '/DATA/,/END/ {
if ( $1 ~ /DATA/ )
{ block=$2 ; i=0 ; file=block
while ( system("test ! -e " file ) )
{ i++ ; file=block"_"i ; print file }
}
print $0 > file
}' input.file
내 문제는 while
루프와 해당 시스템 호출에 있습니다.
system("test -e " file)
존재하면 TRUE이고 file
아직 존재하지 않으면 FALSE가 되기를 원합니다 . 즉, 루프가 존재하는 경우에만 루프가 실행되기 시작하고 (새) 루프가 아직 존재하지 않으면 중단됩니다.file
while
file
file
그러나 사용하면 system("test -e " file)
(그리고 사용하면 장황해집니다 print file
.) 동일한 이름의 무한 루프가 증가하고 정수 접미사가 증가하며 대신 system("test !-e " file)
원하는 결과가 제공됩니다.
그래서 제가 예상했던 것과 정반대였습니다.
답변1
내 생각엔 문제는 종료 상태 test
와 루프 조건 while
사이의 TRUE와 FALSE의 서로 다른 정의 에 있습니다 awk
.
양수 test
명령의 종료 코드는 0
TRUE이고, 음수 명령의 종료 코드는 1
FALSE입니다.
그러나 awk
루프 내에서는 FALSE 및 TRUE로 while
해석되므로 정의는 정반대입니다.0
1
예를 들어:
awk '{ while ( 0 ) ; { print "0" } }' file
아무런 출력도 생성하지 않지만
awk '{ while (1) ; { print "1" } }' file
무한한 s를 인쇄합니다 1
.
따라서 가장 좋은 방법은 다음 조합을 지정하는 것입니다.
while ( system("command") == 0 )
또는
while ( system("command") == 1 )
각기.
그래서 내가 아는 한
while ( system("test -e " file ) == 0 )
예상되는 동작을 보여줍니다.
답변2
awk
system()
실행한 명령의 종료 상태를 반환합니다. 성공하면 0, 실패하면 != 0입니다. 간단한 예를 들어 다음을 실행해 볼 수 있습니다.
v = system("date");
v는 0이 될 것이다
실행하는 경우:
v = system("dat");
v는 127이거나 0이 아닌 값일 수 있으며 dat 명령이 없거나 찾을 수 없는 경우 운영 체제는 오류를 반환합니다.
답변3
무슨 뜻인지 이해한다면, 목표는 input.file의 내용을 다양한 파일로 추출하여 동일한 이름을 가진 블록을 잃지 않는 것입니다.
이런 경우이고 추출하기 전에 대상 디렉터리가 항상 비어 있는 경우 더 나은(더 빠른) 솔루션이 있습니다.
awk '
/DATA/{
block=$2;
n = blocks[block]++;
file=block (n? "_" n: "");
}
/DATA/,/END/{
print > file
}' input.file
이렇게 하면 awk는 파일이 존재하는지 테스트하기 위해 새 쉘을 N 번 실행할 필요가 없습니다.
노트:
- awk의 필드 구분 기호가 이미 공백이므로 BEGIN 블록이 필요하지 않습니다.
'\'
작은따옴표는 이미 여러 줄이므로 줄 끝은 필요하지 않습니다.