echo
내 행렬의 요소를 인쇄할 때 문제가 있습니다. 첫 번째 루프에서 주석 처리를 제거하면 echo ${matrix[$i,$j]}
프로그램이 제대로 작동하지만 두 번째 루프에서 인쇄하려고 하면 ${matrix[$i,$j]}
출력이 null 문자입니다. 목표는 파일에서 행렬을 읽고 스크립트에 선언된 행렬을 내 행렬에 할당하는 것입니다.
function readMatrixFromFile() {
local file="$1"
declare -A matrix
local num_rows=$(awk 'NR==1 {print $3}' $1)
local num_colums=$(awk 'NR==2 {print $3}' $1)
for ((i=3;i<=num_rows+2;i++)) do
for ((j=1;j<=num_colums;j++)) do
k=i-2
matrix[$k,$j]=$(awk -v row=$i -v col=$j 'NR==row {print $col}' $file)
#echo ${matrix[$i,$j]}
done
done
for ((i=1;i<=num_rows;i++)) do
for ((j=1;j<=num_colums;j++)) do
echo ${matrix[$i,$j]}
done
echo
done
}
function Main() {
readMatrixFromFile Matrix3.txt
}
Main
이것은 Matrix3.txt입니다.
출력은 다음과 같습니다.
답변1
#!/bin/bash
declare -A m
read_matrix() {
local i=0
local line
local j
# Ignore the first 2 lines containing size of the matrix
read rows
read cols
while read -r line; do
j=0
# split on spaces
for v in `echo $line`; do
m[$i,$j]="$v"
j=$((j+1))
done
i=$((i+1))
done
}
read_matrix < matrix.file
echo ${m[1,2]}
답변2
나는 이것이 지역 변수 범위 지정과 전역 변수 범위 지정 문제인 것으로 생각합니다.
데이터를 추출하려고 할 때 유사한 "빈" 배열을 발견했지만 함수 내부에 선언된 배열의 내용은 함수 내에서 정의했기 때문에 함수 내에서만 검색할 수 있다고 판단했습니다(원본 게시물에서는 이것이 정확히 내 상황임을 보여주었습니다).
참고: 스크립트의 MAIN 섹션 앞에 함수를 배치할 수 있으며 그 사용은 아래의 함수 호출과 연결되어 있으므로 문제가 되지 않습니다.
BASH 스크립트의 주요 부분에 있는 루프 내에서 조작할 수 있도록 데이터 테이블을 2D 배열로 로드합니다. 위의 내용이 함수 정의 범위 내에 완전히 포함되어 있으므로 아래의 내용이 위의 내용보다 먼저 실행됩니다.
#!/bin/bash
echo "Let's first define the function before the Main Body of Script"
function DEFINESCOPE {
for ((Row=1;Row<=num_rows;Row++))
do
for ((Col=1;Col<=num_columns;Col++))
do
RowData=`cat $STATSFile | head -${Row} | tail -1 | awk -v c1=$Col -F\, '{print $c1}' | sed -e 's/"//g'`
matrix[$Row,$Col]=$RowData
echo "Checking to see if the loaded data can be pulled: Matrix[$Row,$Col] = ${matrix[$Row,$Col]}"
done
done
}
echo "End of Function DEFINESCOPE"
echo "Start of MAIN part of script"
STATSFile="STATSFile"
cat $STATSFile
declare -A matrix
echo "THIS IS THE FUNCTION CALL WHERE THE DATA IS LOADED per the above code"
DEFINESCOPE
echo "NOW TO PULL THE DATA WHILE IN THE MAIN PART OF THE SCRIPT"
echo "In this case I want to start by skipping over the first 3 columns and then walk the rows for each column"
StartRow="1"
StartCol="4"
Row=$StartRow
Col=$StartCol
for ((Col=${StartCol};Col<=num_columns;Col++))
do
Row=$StartRow
echo "Current Position: Matrix[$Row,$Col] = ${matrix[${Row},${Col}]}"
ReportType=${matrix[$Row,$Col]}
echo "============================================="
echo "Walking NEW Report Type: $ReportType"
for ((Row=${StartRow};Row<=num_rows;Row++))
do
echo "Using a CASE statement instead of a bunch of if.then.else.fi..."
echo "Pull Metric Data for C/H/M/L Severity Row Counts"
echo "Determine which type of row we're examining and then assign values"
case "${matrix[$Row,1]}" in
Critical)
Criticals=${matrix[$Row,$Col]}
echo "Setting Severity Count for Criticals: $Criticals"
;;
Highs)
Highs=${matrix[$Row,$Col]}
echo "Setting Severity Count for Highs: $Highs"
;;
Mediums)
Mediums=${matrix[$Row,$Col]}
echo "Setting Severity Count for Mediums: $Mediums"
;;
Lows)
Lows=${matrix[$Row,$Col]}
echo "Setting Severity Count for Lows: $Lows"
;;
*)
echo "Case *): Does not match: matrix[Row,1]: ${matrix[$Row,1]}"
;;
esac
echo "Current Data Position: matrix[Row,Col]: ${matrix[$Row,$Col]}"
echo "Current Row Position: matrix[Row,1]: ${matrix[$Row,1]}"
done
done
echo "Thus, I moved the 'declare' statement to the main part of the bash"
echo "script, prior to the function call, loaded the data in the function," echo "and then I was then able to pull data from the array when in the main part of the script."
echo "Bottom Line: declare your array in the main part of the script, before you call a function/subroutine to load or output array data."