연관 배열에 항목을 추가할 때 "잘못된 배열 첨자" 오류

연관 배열에 항목을 추가할 때 "잘못된 배열 첨자" 오류

원래 쿼리가 완전히 답변되었으므로 이에 대한 새 쿼리를 시작하는 것이 좋을 것 같습니다(감사합니다!).

두 개의 파일이 있는데 둘 다 postgresql 명령의 출력입니다. 첫 번째 항목(/tmp/inventory.list)은 원래 쿼리의 주제였습니다.Bash 배열을 사용하여 테이블을 ini 파일로 변환, @choroba가 친절하게 제안한 배열 명령을 사용합니다. 두 번째 파일(/tmp/inventory2.list)의 형식이 첫 번째 파일과 매우 유사하다는 점을 감안할 때 배열 스크립트를 조정하여 이 파일을 유사하게 처리할 수 있다고 생각했지만 분명히 뭔가를 엉망으로 만들었습니다.

내 입력 파일 /tmp/inventory2.list의 형식은 다음과 같습니다.

environment1 | hostname1.environment1.domain
environment1 | hostname2.environment1.domain
environment1 | hostname3.environment1.domain
environment2 | hostname4.environment2.domain
environment2 | hostname5.environment2.domain
environment3 | hostname6.environment3.domain

그룹화된 형식으로 다른 파일을 읽고 써야 합니다.

[environment1]
hostname1.environment1.domain
hostname2.environment1.domain
hostname3.environment1.domain

[environment2]
hostname4.environment2.domain
hostname5.environment2.domain

[environment3]
hostname6.environment3.domain

환경 그룹 사이에는 줄 간격이 있어야 하고, 그룹 이름은 알파벳 순서로 표시되어야 하며, 호스트 이름은 그룹 내에서 알파벳 순으로 정렬되어야 합니다. 환경 그룹당 호스트 이름이 여러 개 있을 수 있지만 각 그룹은 한 번만 나타날 수 있습니다.

상황을 복잡하게 만들기 위해 입력 파일 끝에 빈 줄이 있는데 postgresql 쿼리에서 이를 생략하도록 할 수 없습니다(-t 또는 --tuples-only는 일반적으로 끝에 기록되는 행 개수 줄을 제거합니다. 그러나 마지막 빈 줄은 제거되지 않습니다.) 따라서 제거해야 하며 새 출력 파일이 작성되지 않습니다.

이 파일을 읽고 올바르게 출력하기 위해 @choroba의 배열 명령을 조정하려고 시도했지만 첫 번째 파일에서는 완벽하게 작동했지만 조정이 작동하지 않았습니다. 나는 가지고있다:

  1 #! /bin/bash
  2
  3 unset -v envs
  4 unset -v hosts
  5 declare -A envs
  6 declare -A hosts
  7 rm -f /tmp/hosts.txt
  8
  9 while IFS='| ' read -r certname role env; do
 10     envs["$role.$env"]+="$certname"$'\n'
 11 done < /tmp/inventory.list
 12
 13 for e in "${!envs[@]}" ; do
 14 #
 15     printf '%s\n' "$e"
 16 done | sort | while read -r e ; do
 17     printf '%s\n' "[$e]" "${envs[$e]}" >> /tmp/hosts.txt
 18 done
 19
 20 while IFS='| ' read -r env certname; do
 21     hosts["$env"]+="$certname"$'\n'
 22 done < /tmp/inventory2.list
 23
 24 for f in "${!hosts[@]}" ; do
 25     printf '%s\n' "$f"
 26 done | sort | while read -r f ; do
 27     printf '%s\n' "[$f]" "${hosts[$f]}" >> /tmp/hosts1.txt
 28 done

9~18행(및 관련 3, 5행)은 @choroba가 제공한 코드이며 /tmp/inventory.list 읽은 파일에서 완벽하게 작동합니다.

20~28행(및 관련 4행과 6행)은 두 번째 파일인 /tmp/inventory2.list를 처리하기 위해 수정한 내용입니다. 실행할 때 오류가 발생합니다.

 line 21: hosts["$env"]: bad array subscript

나는 이 문제를 몇 시간 동안 고민해 보았지만 내가 수정한 스니펫에는 아무런 문제도 발견할 수 없습니다. 누구든지 어떤 아이디어가 있습니까?

답변1

입력 파일에 빈 줄이 있다고 언급했는데, 그것이 /tmp/inventory2.list에 있다면 그게 문제입니다.

여러 가지 방법으로 해결되었습니다. 그 중 하나는 $env 변수를 사용하기 전에 테스트하는 것입니다.

[ -n "$env" ] && hosts["$env"]+="$certname"$'\n'

또 다른 방법은 파일을 읽기 전에 파일의 모든 문자를 검색하는 것입니다.

grep . inventory2.list | while IFS='| ' read -r env certname; do
  hosts["$env"]+="$certname"$'\n'
done

("빈" 줄에 공백이 있으면 grep을 조정하십시오. 이와 유사한 것 grep [a-z])

관련 정보