탭으로 구분된 파일을 구문 분석하는 bash 스크립트를 작성 중입니다. 파일에 "prompt"라는 단어가 포함되어 있으면 스크립트는 사용자에게 값을 입력하도록 요청해야 합니다.
파일을 읽을 때 "읽기"를 단순히 건너뛰기 때문에 "읽기" 명령이 표준 입력에서 읽지 못하는 것 같습니다.
파일과 표준입력(stdin)에서 데이터를 읽는 솔루션을 갖고 있는 사람이 있나요?
참고: 이 스크립트는 Git Bash 및 MacOS에서 실행되어야 합니다.
다음은 실패한 작은 코드 예제입니다.
#!/bin/bash
#for debugging
set "-x"
while IFS=$'\r' read -r line || [[ -n "$line" ]]; do
[[ -z $line ]] && continue
IFS=$'\t' read -a fields <<<"$line"
command=${fields[0]}
echo "PROCESSING "$command
if [[ "prompt" = $command ]]; then
read -p 'Please enter a value: ' aValue
echo
else
echo "Doing something else for "$command
fi
done < "$1"
산출:
$ ./promptTest.sh promptTest.tsv
+ IFS=$'\r'
+ read -r line
+ [[ -z something else ]]
+ IFS=' '
+ read -a fields
+ command=something
+ echo 'PROCESSING something'
PROCESSING something
+ [[ prompt = something ]]
+ echo 'Doing something else for something'
Doing something else for something
+ IFS=$'\r'
+ read -r line
+ [[ -z prompt ]]
+ IFS=' '
+ read -a fields
+ command=prompt
+ echo 'PROCESSING prompt'
PROCESSING prompt
+ [[ prompt = prompt ]]
+ read -p 'Please enter a value: ' aValue
+ echo
+ IFS=$'\r'
+ read -r line
+ [[ -n '' ]]
TSV 파일 예:
$ cat promptTest.tsv
something else
prompt
otherthing nelse
답변1
가장 간단한 방법은 /dev/tty
키보드 입력을 읽는 것으로 사용하는 것입니다.
예를 들어:
#!/bin/bash
echo hello | while read line
do
echo We read the line: $line
echo is this correct?
read answer < /dev/tty
echo You responded $answer
done
터미널에서 실행하지 않고 입력이 프로그램으로 리디렉션되는 것을 허용하지 않으면 프로그램이 중단되지만 그렇지 않으면 정상적으로 작동합니다.
보다 일반적으로는 원래 표준 입력을 기반으로 새 파일 핸들을 가져와서 읽을 수 있습니다. 라인 exec
과read
#!/bin/bash
exec 3<&0
echo hello | while read line
do
echo We read the line: $line
echo is this correct?
read answer <&3
echo You responded $answer
done
두 경우 모두 프로그램은 다음과 같습니다.
% ./y
We read the line: hello
is this correct?
yes
You responded yes
두 번째 변형은 입력 리디렉션도 허용합니다.
% echo yes | ./y
We read the line: hello
is this correct?
You responded yes
답변2
이 SO Q&A의 제목은 다음과 같습니다.Bash에서 파일이나 표준 입력을 읽는 방법은 무엇입니까?찾고 있는 것과 유사한 작업을 수행하는 방법을 강조하는 이 방법을 보여줍니다.
while read line
do
echo "$line"
done < "${1:-/dev/stdin}"
답변3
리디렉션하기 전에 표준 입력을 복사할 수 있습니다.
#!/bin/bash
# Assuming here fd 4 is unused. Dup file descriptor 0 (stdin) to
# file descriptor 4
exec 4<&0
while read x; do # Read from stdin (the file b/c of redirect below)
echo "From $1: $x"
read y <&4 # Read from file descriptor 4 (the original stdin)
echo "From keyboard: $y"
done < "$1"