![Bash에서 한 번에 한 줄씩 여러 파일 읽기](https://linux55.com/image/60955/Bash%EC%97%90%EC%84%9C%20%ED%95%9C%20%EB%B2%88%EC%97%90%20%ED%95%9C%20%EC%A4%84%EC%94%A9%20%EC%97%AC%EB%9F%AC%20%ED%8C%8C%EC%9D%BC%20%EC%9D%BD%EA%B8%B0.png)
나는 Bash에서 명령을 읽는 기본 방법을 알고 있습니다.
cal | while IFS= read -r line ; do
echo X${line}X
done
하지만 루프의 여러 파일/명령에서 한 줄을 읽으려면 어떻게 해야 합니까? 명명된 파이프를 시도해 보았지만 한 줄만 뱉어냈습니다.
$ cal > myfifo &
$ IFS= read -r line < myfifo
[cal exits]
$ echo $line
February 2015
그래서 내가 정말로 원하는 것은 이것이다.
while [all pipes are not done]; do
IFS=
read line1 < pipe1 # reading one line from this one
read line2 < pipe2 # and one line from this one
read line3 < pipe3 # and one line from this one
print things with $line1 $line2 and $line3
done
전반적으로 제가 하고 싶은 것은 cal의 데이터를 3개월 동안 처리하고 Conky가 사용할 수 있도록 몇 가지 색상을 지정하는 것입니다. 솔직히 말해서 그것은 야크를 면도하는 것과 같아서 현재로서는 학술적이고 "학습 경험"이 되었습니다.
답변1
paste
가장 간단한 방법이 될 것입니다. 그러나 bash 파일 설명자와 프로세스 대체를 사용하면 다음과 같습니다.
exec 3< <(cal 1 2015)
exec 4< <(cal 2 2015)
exec 5< <(cal 3 2015)
while IFS= read -r -u3 line1; do
IFS= read -r -u4 line2
IFS= read -r -u5 line3
printf "%-25s%-25s%-25s\n" "$line1" "$line2" "$line3"
done
exec 3<&-
exec 4<&-
exec 5<&-
January 2015 February 2015 March 2015
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 6 7
4 5 6 7 8 9 10 8 9 10 11 12 13 14 8 9 10 11 12 13 14
11 12 13 14 15 16 17 15 16 17 18 19 20 21 15 16 17 18 19 20 21
18 19 20 21 22 23 24 22 23 24 25 26 27 28 22 23 24 25 26 27 28
25 26 27 28 29 30 31 29 30 31
답변2
paste
출력을 결합한 다음 한 줄씩 읽을 수 있습니다 .
paste -d $'\n' <(foo) <(bar) <(cat baz) | while IFS= read -r line1
do
IFS= read -r line2 || break
IFS= read -r line3 || break
# ..
done
답변3
이것이 필요한 구조입니다.
FIFO가 올바른 라인에 있지만 라인을 읽을 때 종료되는 이유는 FIFO를 열고 라인을 읽은 다음 다시 닫았 cal
기 때문입니다 . read -r line < myfifo
파이프를 닫으면 더 이상 쓰기(읽기) 작업이 불가능하다는 신호를 다른 쪽 끝에 보냅니다. 그래서 cal
그만뒀어요.
# Create the FIFOs
mknod pipe1 p
mknod pipe2 p
mknod pipe3 p
# Start off the commands
command1 >pipe1 &
command2 >pipe2 &
command3 >pipe3 &
# Attach file descriptors to the other side of the FIFOs
exec 11<pipe1 12<pipe2 13<pipe3
# Loop
IS_MORE=0
while [[ 0 eq $IS_MORE ]]
do
IS_MORE=1
read LINE1 <&11 && IS_MORE=0
read LINE2 <&12 && IS_MORE=0
read LINE3 <&13 && IS_MORE=0
# ...
done
# Close descriptors and remove the FIFOs
exec 11<&- 12<&- 13<&-
rm -f pipe1 pipe2 pipe3
# Clean up the dead processes (zombies)
wait
# ...
답변4
while \
IFS= read -r -u3 line1;do
IFS= read -r -u4 line2
IFS= read -r -u5 line3
printf "%-25s%-25s%-25s\n" "$line1" "$line2" "$line3"
done 3< <(cal -h 1 2018) 4< <(cal -h 2 2018) 5< <(cal -h 3 2018)
또는 3개월이 인접해 있는 경우 다음과 같을 수 있습니다.
while IFS= read -r;do
printf "%s\n" "${REPLY}"
done < <(cal -A 1 -B 1 -h 8 2018)