gawk가 stdin으로부터 연속 스트림을 읽을 때 RS에 정규 표현식을 사용하면 중단되는 문제 해결
gawk
를 사용하여 stdin
으로부터 연속 스트림을 읽을 때 RS
변수에 정규 표현식을 사용하면 마지막 레코드를 처리하지 못하고 중단되는 문제가 발생합니다. 이는 gawk
가 다음 레코드를 위해 더 많은 데이터를 기다리기 때문입니다.
예시:
cat -u example.txt - | gawk 'BEGIN { RS = "=|;"; } { print $0; fflush(); }'
위 예시에서 cat
명령은 example.txt
파일의 내용과 stdin
의 내용을 gawk
스크립트에 파이프합니다. gawk
스크립트는 RS
변수를 =|;
정규 표현식으로 설정하여 레코드 구분자로 사용합니다. 하지만 스크립트는 마지막 레코드를 처리하지 못하고 중단됩니다.
해결 방법:
이 문제를 해결하려면 다음과 같은 방법을 사용할 수 있습니다.
stdin
을 닫습니다.
stdin
을 닫으면 gawk
가 더 이상 데이터를 기다리지 않고 마지막 레코드를 처리합니다. 다음과 같이 cat
명령에 -n
옵션을 사용하여 stdin
을 닫을 수 있습니다.
cat -n example.txt - | gawk 'BEGIN { RS = "=|;"; } { print $0; fflush(); }'
RS
변수를 문자열로 설정합니다.
RS
변수를 문자열로 설정하면 gawk
가 정규 표현식 대신 문자열을 레코드 구분자로 사용합니다. 다음과 같이 RS
변수를 =|;
문자열로 설정할 수 있습니다.
gawk 'BEGIN { RS = "=|;"; } { print $0; fflush(); }' < example.txt
getline()
함수를 사용합니다.
getline()
함수를 사용하여 stdin
으로부터 한 줄씩 데이터를 읽을 수 있습니다. 다음과 같이 getline()
함수를 사용하여 마지막 레코드까지 처리할 수 있습니다.
BEGIN { RS = ""; }
while (getline < ARGV[1]) {
# 레코드 처리
}
예제 코드
cat -n example.txt - | gawk 'BEGIN { RS = "=|;"; } { print $0; fflush(); }'
gawk 'BEGIN { RS = "=|;"; } { print $0; fflush(); }' < example.txt
BEGIN { RS = ""; }
while (getline < ARGV[1]) {
# 레코드 처리
}
설명:
- 위 예제 코드는 모두
example.txt
파일의 내용과stdin
의 내용을 처리합니다. - 첫 번째 예제 코드는
cat
명령에-n
옵션을 사용하여stdin
을 닫습니다. - 두 번째 예제 코드는
gawk
스크립트에서RS
변수를=|;
문자열로 설정합니다. - 세 번째 예제 코드는
gawk
스크립트에서getline()
함수를 사용하여stdin
으로부터 한 줄씩 데이터를 읽습니다.
주의:
- 위 예제 코드는 예시일 뿐이며 사용자의 실제 요구 사항에 따라 변경해야 할 수도 있습니다.
gawk
버전 및 사용 환경에 따라 몇 가지 구문이 다를 수 있습니다.
gawk
가 stdin
으로부터 연속 스트림을 읽을 때 RS
에 정규 표현식을 사용하는 문제를 해결하는 다른 방법
getline() 함수와 match() 함수를 사용합니다.
다음과 같이 getline()
함수와 match()
함수를 사용하여 각 레코드의 끝을 찾아 마지막 레코드까지 처리할 수 있습니다.
BEGIN { RS = ""; }
while (getline < ARGV[1]) {
# 레코드 끝 찾기
if (match($0, /=\|;/)) {
# 레코드 처리
}
}
NF 변수를 사용합니다.
다음과 같이 NF
변수를 사용하여 레코드의 마지막 필드를 확인하여 마지막 레코드까지 처리할 수 있습니다.
BEGIN { RS = ""; }
while (getline < ARGV[1]) {
# 레코드 처리
if (NF == 0) {
# 마지막 레코드 처리
}
}
while 루프를 수정합니다.
다음과 같이 while
루프를 수정하여 EOF
(End-Of-File) 조건을 사용하여 마지막 레코드까지 처리할 수 있습니다.
BEGIN { RS = ""; }
while (getline < ARGV[1]) {
# 레코드 처리
}
if (NR == FNR) {
# 마지막 레코드 처리
}
regex shell awk