저는 bash 쉘 스크립팅을 배우고 있으며 awk 등이 아닌 순수한 bash 방식을 찾고 있습니다.
정보를 기반으로 표현식을 작성할 수 있도록 for 루프를 사용하여 터미널에 매개변수로 제출된 두 파일의 내용을 반복하려고 합니다.
파일 내용은 탭으로 구분됩니다. 이 파일에는 확장자가 없습니다. 다음은 평가하려는 파일 정보 유형의 예입니다.
$cat file1
1 2 3
40 50 60
$cat file2
10 20 30
40 50 60
제가 작성한 코드는 다음과 같습니다.
read line1 < "file1"
read line2 < "file2"
difference=0
#I can see the contents of file1 with the below code and by changing the code
#slightly I can see the contents of file2 as well using the following code:
for index1 in $line1
do
echo "The contents of index1 are: $index1"
done
#But I am trying to do something like this which isn't working:
for index1 in $line1, index2 in $line2
do
difference=$(expr $index1 - $index2)
echo $difference
done
답변1
확실히 가능하지만 즐겁지는 않습니다. 사실, 사물에 다르게 접근하고 싶을 것입니다.
이러한 특정 파일과 이 작업의 경우 이 스크립트는 아마도 가장 간단하며 while
루프 대신 단일 루프를 사용합니다 for
.
exec 3<file2
while read a1 a2 a3 && read b1 b2 b3 <&3
do
echo $((a1 - b1))
echo $((a2 - b2))
echo $((a3 - b3))
done < file1
각 파일은 고정된 3열 구조로 되어 있으며 모든 파일을 한 번에 읽습니다. file2
파일 설명자 3에서 열기(exec 3<file2
) 독립적으로 읽을 수 있습니다 file1
. 작성한 내용은 파일을 열고 읽습니다.첫 번째매번 줄을 서세요. 이 read
명령은 첫 번째 단어를 에 x1
, 두 번째 단어를 에 x2
, 나머지 줄을 `x3에 넣습니다.
두 목록을 함께 "압착"하거나 병렬 for 루프를 작성하는 기본 제공되거나 비교적 쉬운 방법은 없습니다. 간단한 배열이나 문자 그대로의 단어 목록 이외의 항목에 대한 for 루프는 불가능하기 어렵고 올바른 배열을 구축하려면 다른 작업을 수행하는 것보다 더 많은 작업이 필요합니다.
열 수가 가변적이라면 이는 더 까다롭지만 다음을 사용할 수 있습니다.mapfile
행에서 배열을 만든 다음 일반 배열 처리를 사용합니다.C형 for
루프각 행에 대해 다음을 수행합니다.
while read line1 && read line2 <&3
do
mapfile -d $'\t' a1 <<<"$line1"
mapfile -d $'\t' a2 <<<"$line2"
for ((i=0; i<${#a1[@]}; i++))
do
echo $((a1[i] - a2[i]))
done
done <file1
a1
그러면 다음을 포함하는 두 개의 배열이 a2
생성 됩니다.탭으로 구분됨요소한 줄에, 줄 길이만큼 반복합니다 file1
(다른 파일의 추가 항목은 무시).
zip
파일의 형식이 올바르고 열 번호가 해당 행과 일치한다고 가정하면 가장 일반적인 근사치는 비슷합니다 while read a b ... done < <(paste <(printf '%s\n' $(<file1)) <(printf '%s\n' $(<file2)))
. 이는 정말 역겨운 일입니다.
즉 말하자면,쉘 스크립트는 이러한 유형의 처리에 적합한 메커니즘이 아닙니다., 반면에 awk(또는 더 나은 경우 적절한 언어)는 이보다 더 적합하고 덜 깨지기 쉽습니다.
위의 스크립트를 보면 구현하기가 지나치게 복잡하고 깨지기 쉬우며 언어가 이를 위해 설계되지 않았기 때문에 따르기가 어렵다는 것을 알 수 있을 것입니다. 이 스크립트는더동일한 목표를 달성하는 다른 방법보다 더 읽기 쉬우나 별 의미는 없습니다.