쉘 스크립트를 작성할 때 제가 하는 대부분의 작업은 Python, Matlab 등의 다른 모듈에서 I/O를 래핑하는 것입니다. 이를 위해 나는 일반적으로 입력/출력 경로가 있는 텍스트 파일이나 유사한 성격의 파일을 사용합니다. 나는 사용할 수 있는 파일에서 한 줄을 읽는 방법을 알고 있습니다.
for file in $(cat $1);
do
code using $file
done
하지만 두 파일의 동일한 줄을 사용하여 작업을 수행하려면 어떻게 해야 합니까? Java와 유사합니다.
while((line1 = file1.readLine()) != null) {
line2 = file2.readLine();
//do something with both lines...
}
Bash에서 이를 수행하는 표준 방법은 무엇입니까?
답변1
exec 3<file1
exec 4<file2
while read line1 <&3 && read line2 <&4
do
echo "line1=$line1 and line2=$line2"
done
exec 3<&-
exec 4<&-
논의하다
위에서는 입력 줄에서 선행 및 후행 공백이 제거되었습니다. 이 공간을 유지하려면
read …
다음으로 바꾸십시오.IFS= read …
위에서 입력의 백슬래시는 이스케이프 문자로 해석됩니다. 이 작업을 수행하지 않으려면 다음
read …
으로 교체하세요.read -r …
read line1 <&3
line1
파일 설명자 3에서 읽습니다. 이는 다음과 같이 동등하게 쓸 수도 있습니다read -u3 line1
.이와 같은 진술 에는
for file in $(cat $1);
알아야 할 몇 가지 문제가 있습니다. 쉘은 파일 내용에 토큰화된 경로 이름 확장을 적용하므로 이를 예상하지 않는 한 다양한 오류가 발생할 수 있습니다.
선택하다
while read line1 <&3 && read line2 <&4
do
echo "line1=$line1 and line2=$line2"
done 3<file1 4<file2
답변2
파일의 행을 반복하려면 다음을 수행하십시오.
while IFS= read -r line; do
echo "read $line"
done <input-file
여러 파일을 반복하려면 다른 파일 설명자에서 해당 파일을 엽니다(참조추가 파일 설명자는 언제 사용됩니까?).
while IFS= read -r line1 <&8 || IFS= read -r line2 <&9; do
echo "read '$line1' from file 1 and '$line2' from file 2"
done 8<input-file1 9<input-file2
가장 긴 파일과 일치하도록 빈 줄로 read <&8 || read <&9
가장 짧은 파일을 완성하십시오 . 두 파일 중 하나의 끝에 도달했을 때 즉시 종료하려면 &&
대신 을 사용하십시오 ||
. 모든 경우를 감지하려면 개별적으로 반환 코드를 확인하십시오.
{
while
IFS= read -r line1 <&8; empty1=$?
IFS= read -r line2 <&9; empty2=$?
[ "$empty1" -ne 0 ] && [ "$empty2" -ne 0 ]
do
echo "read '$line1' from file 1 and '$line2' from file 2"
done
if [ "$empty1" -ne 0 ]; then
echo "Finishing processing file 1"
…
fi
if [ "$empty2" -ne 0 ]; then
echo "Finishing processing file 2"
…
fi
} 8<input-file1 9<input-file2
또는 두 파일을 함께 연결할 수 있습니다. 이것paste
이를 위해서는 명령이 편리합니다. 기본적으로 탭별로 줄을 구분하고( -d
다른 구분 기호를 선택하려면 전달) 빈 줄로 파일을 완성합니다. 파일에 탭 문자가 포함되어 있지 않으면 입력 줄이 명확하게 구분됩니다.
tab=$(printf \\t)
paste input-file1 input-file2 |
while IFS=$tab read -r line1 line2; do … done
셸은 텍스트 처리 속도가 그리 빠르지 않습니다. 중대형 입력에는 보다 전문화된 도구가 가장 적합합니다. 전처리를 사용하면 paste
후처리를 위해 두 파일을 쉽게 압축할 수 있습니다. 행을 읽을 때 더 많은 제어가 필요한 경우 awk는 해당 명령을 사용하여 이를 수행 할 수 있습니다 getline
(셸의 와 유사 ).read