스토리지 디스크에 대한 다음 입력을 다음 형식의 출력으로 바꾸고 싶습니다. 아래 스크립트는 거의 효과적이었습니다. 그러나 이것은 T0에서는 작동하지 않습니다. "replaceTier" 함수에서 숫자 끝의 0을 올바르게 읽는 데 문제가 있는 것 같습니다.
교정하는 것을 도와주실 수 있나요? 미리 감사드립니다.
**INPUT IN FILE:**
displayName=00:19:78
sizeInKB=26214720
dpPoolID=1
displayName=00:FE:B0
sizeInKB=2251536384
dpPoolID=110
displayName=00:FE:B1
sizeInKB=2251536384
dpPoolID=110
**EXPECTED OUTPUT:**
1978,T1
FEB0,T0
FEB1,T0
replaceTier=(
{1,11,12,13,14,15,16,17,18,19,51,61,71,81,100}:T1
{2,21,22,23,24}:T2
3:T3
{10,110}:T0
90:SVC_T1
91:SVC_T2
92:SVC_T1
)
#
while read -r name serial model uid
do
cat "$DIR"/"$name"_disks.log | grep -v 'sizeInKB' | cut -d "=" -f2 | sed 's/\://g' | xargs -n2 | sed 's/\ /\,/g' | cut -c 3- | grep -v ',-1' > "$DIR"/"$name"_output.log
for row in "${replaceTier[@]}"; do
original="$(echo $row | cut -d: -f1)";
new="$(echo $row | cut -d: -f2)";
sed -i -e "s/,${original}.*/,${new}/g" "$DIR"/"$name"_output.log;
done
done < /storage/logs/HDSlist.txt
답변1
감사해요. 네가 옳아. '.*'는 '$'로 바꿔야 합니다. 이제는 잘 작동합니다. 반품거기나에게도 꼭 필요한 정보를 찾았다.
sed -i -e "s/,${original}$/,${new}/g" "$DIR"/"$name"_output.log;
당신의 노력에 감사드립니다.
답변2
문제는 정규식 끝에 있는 와일드카드입니다.
s/,${original}.*/,${new}/g
.*
110을 테이블의 첫 번째인 11 또는 1과 일치 시키므로 replaceTier
110은 T0 대신 T1(1:T1 매핑에서)으로 변환됩니다.
대신 번역하려는 숫자와 정확히 일치하는 항목을 원하므로 정확한 숫자만 일치하도록 앵커(줄 끝과 일치)를 제거 .*
하고 추가하세요 .$
s/,${original}\$/,${new}/g
그런데, 로그 파일 구문 분석이 너무 복잡한 것 같습니다. 스크립트를 사용한다고 가정하면 bash
다음과 같이 수행합니다.
while read -r displayName; do
# Read two more rows of data from the
# input file.
read -r sizeInKB # ignored
read -r dpPoolID
# Process displayName, remove everything
# up to the first ":", then drop the
# remaining ":" in the middle.
displayName=${displayName#*:}
displayName=${displayName/:/}
# Look up dpPoolID in replaceTier.
tier=""
for row in "${replaceTier[@]}"; do
# Split row into id:tier.
id=${row%%:*}
if [[ "$dpPoolID" = "$id" ]]; then
tier=${row#*:}
break
fi
done
if [[ -n "$tier" ]]; then
# Only print when tier was found, so skip
# invalid dpPoolIDs such as -1, etc.
printf "%s,%s\n" "$displayName" "$tier"
fi
done <"$DIR"/"$name"_disks.log >"$DIR"/"$name"_output.log
이는 동일한 파일에 대한 다중 읽기 및 쓰기를 방지할 뿐만 아니라 bash
내장 함수(no grep
, sed
, cut
, xargs
)만 사용하므로 외부 프로세스를 생성하는 데 따른 많은 오버헤드가 사라졌습니다.
하지만 이 경우에도 연관 배열을 사용하면 개선의 여지가 있습니다 replaceTier
. 이 경우 각 행에서 완전히 반복하는 대신 직접 조회를 수행할 수 있습니다.
다음을 사용하여 이러한 연관 배열을 정의할 수 있습니다.
replaceTier=(
[1]=T1
[12]=T1
[13]=T1
[14]=T1
...
[100]=T1
[2]=T2
[21]=T2
...
[24]=T2
[3]=T3
[10]=T0
[110]=T0
[90]=SVC_T1
[91]=SVC_T2
[92]=SVC_T1
)
이 경우 가장 안쪽 for
루프를 직접 조회로 단순화할 수 있습니다.
tier=${replaceTier[$id]}
이는 특히 테이블 크기가 replaceTier
커질수록 더욱 효율적입니다.