보고 있다이 문제awk
, 파일이 표준 입력으로 파이프되면 사용자 입력을 읽을 수 없지만 명령줄 인수로 제공된 파일에서 입력을 읽으면 예상대로 작동한다는 것을 확인했습니다 .
예를 들어 스크립트에 다음 BEGIN 블록이 있는 경우 awk
:
BEGIN {
printf "Enter input: "
getline var < "-"
}
이렇게 실행하면 awk -f ./script.awk file.txt
사용자에게 입력하라는 메시지가 표시되고 처리가 계속됩니다 file.txt
. 그러나 이렇게 실행하면 cat file.txt | awk -f ./script.awk
awk가 파이프에서 가져온 내용을 사용자 입력으로 해석할 것이라고 생각됩니다(따라서 첫 번째 행이 getline
채워집니다 ).var
file.txt
awk
파일에서 읽는 것처럼 동작하지만 파이프에서 사용하는 방법이 있습니까 ?
물론 임시 파일을 사용할 수도 있지만 이는 우아함과는 거리가 멀습니다.
답변1
프로세스 대체는 간단한 경우에 작동할 수 있지만 파이프된 데이터를 처리하는 동안 콘솔 사용자와 대화할 수 있는 일반적인 접근 방식은 다음과 같습니다.
BEGIN {
printf "Enter input: " > "/dev/tty"
getline var < "/dev/tty"
print var
}
답변2
임시 파일 외에도 프로세스 교체를 위한 셸의 지원을 사용할 수도 있습니다(이는 bash
, zsh
또는 일부 구현 ksh
(이 기능은 ksh88에서 도입됨)을 가정함).
awk -f ./script.awk <(cat file.txt)
이는 읽을 때 첨부된 명령의 출력을 포함하는 구문 awk
대신 파일 이름을 제공합니다 .<(...)
답변3
이것이 귀하의 작업 흐름에 적합하다면 awk 자체가 파이프를 열도록 할 수 있습니다. Elements로는 이 작업을 수행할 수 없으므로 ARGV
파이프에서 읽은 줄에서 awk의 자동 반복을 얻을 수 없습니다. 대신 awk는 명령줄 인수로 전달된 파일에서 읽거나 파일 인수가 없는 경우 표준 입력에서 읽습니다.
{
printf "Enter input: "
getline var
while (("cat file.txt" | getline) > 0) { … }
}
이 구조는 여러분의 장난감 예제에 맞지 않지만 실제 문제에 맞을 수 있기 때문에 언급하겠습니다.
답변4
시스템이 /dev/fd/[num]
연결을 지원하거나 awk
GNU인 경우 awk
다음에서 작동합니다 awk -f ./script.awk file.txt
.
{ some_cmd | 3<&0 <&4 4<&- awk -f ./script.awk /dev/fd/3; } 4<&0