Bash를 사용하여 다차원 배열을 만들어야 하는데 Bash에는 다차원 배열과 같은 것이 없다는 것을 읽었습니다.
가능한 데이터, 모양 및 필요한 데이터는 다음과 같습니다. 이것은 bash 배열이 아닙니다.
DATACOL = [
"1"=>("Santiago","Barcelona","AWG","6792992","Male"),
"2"=>("Santi","Texas","BGG","6792992","Male"),
"3"=>("Tiago","Rio","GHA","6792992","Female")
]
간단한 스크립트로 비슷한 작업을 어떻게 수행할 수 있나요? 저는 bash를 처음 접했습니다.
답변1
넌 몰라. 다차원 배열과 같은 것이 필요하다면 이는 쉘이 아닌 실제 프로그래밍 언어를 사용해야 한다는 것을 의미합니다. 쉘은 실제로 프로그래밍 언어는 아니지만 하나로 (악용) 사용될 수 있지만 이는 단순한 용도로만 사용해야 합니다. 불행하게도 많은 사람들은 셸이 모든 상황에 적합한 도구라고 생각하는 것 같습니다. 이로 인해 특정 용도로 설계된 도구를 사용하는 대신 셸이 할 수 없거나 매우 제대로 수행할 수 없는 일을 하려고 노력하는 데 많은 노력이 낭비됩니다. 특정 상황. 일하다.
즉, 다음을 사용하여 무언가를 하나로 모을 수 있습니다.이름 참조:
선언이나 로컬 내장 기능(Bash 내장 기능 참조)의 -n 옵션을 사용하여 변수에 nameref 속성을 할당하여 다른 변수에 대한 참조나 nameref를 생성할 수 있습니다. 이를 통해 변수를 간접적으로 조작할 수 있습니다. nameref 변수가 참조, 할당, 설정 해제되거나 해당 속성이 수정될 때마다(nameref 속성 자체를 사용하거나 변경하는 경우 제외) nameref 변수의 값으로 지정된 변수에 대해 작업이 실제로 수행됩니다. nameref는 일반적으로 쉘 함수에서 이름이 함수에 인수로 전달되는 변수를 참조하는 데 사용됩니다. 예를 들어 변수 이름을 셸 함수의 첫 번째 인수로 전달하는 경우 다음을 실행합니다.
declare -n ref=$1
함수 내에서 첫 번째 매개변수로 전달된 변수 이름을 값으로 갖는 nameref 변수 ref가 생성됩니다. ref에 대한 참조 및 할당과 해당 속성에 대한 변경은 이름이 $1로 전달되는 변수에 대한 참조, 할당 및 속성 수정으로 처리됩니다.
예를 들어 다음과 같습니다.
#!/bin/bash
data1=("Santiago" "Barcelona" "AWG" "6792992" "Male")
data2=("Santi" "Texas" "BGG" "6792992" "Male")
data3=("Tiago" "Rio" "GHA" "6792992" "Female")
datacol=("data1" "data2" "data3")
for arrayName in "${datacol[@]}"; do
declare -n array="$arrayName"
echo "The second element of the array '$arrayName' is: ${array[1]}"
done
다음을 생성합니다.
$ foo.sh
The second element of the array 'data1' is: Barcelona
The second element of the array 'data2' is: Texas
The second element of the array 'data3' is: Rio
정말 복잡하고 깨지기 쉬우며 노력할 가치가 없습니다. 대신 실제 스크립트 언어를 사용하십시오.
답변2
몇 가지 트릭 없이는 Bash에서 할 수 없습니다. 그러나 Ksh93에는 기본 다차원 배열이 있습니다.
일반적인 기술은 declare -A arr
와 같은 키 1,2
와 쉼표로 구분된 여러 인덱스가 있는 연관 배열( )을 사용하는 것입니다. 개별 "행"이나 "열"을 반복하는 것은 그렇게 간단하지 않습니다. 이는 AWK가 다차원 배열을 구현하는 방법이기도 합니다.GNU AWK 매뉴얼.
ksh에서:
arr=((a b c) (d e f)) # 3x2
arr[2]=(g h i) # one more row
arr[0][2]=x # change a value
typeset -p arr
echo ---
for i in ${!arr[@]}; do # ${!arr[@]} gives the indexes
for j in ${!arr[i][@]}; do
echo -n "${arr[i][j]} ";
done;
echo;
done
인쇄
typeset -a arr=((a b x) (d e f) (g h i) )
---
a b x
d e f
g h i
그러나 실제로 이것은 사용 사례가 매우 구체적이지 않는 한 Python(또는 Perl 또는...) 사용을 고려해야 하는 경우 중 하나입니다. 쉘 언어를 사용하면 외부 프로그램을 쉽게 시작할 수 있지만 데이터 구조 작업은 훨씬 더 어렵습니다.
답변3
배열을 "남용"하면 원하는 효과를 얻을 수 있다는 것을 발견했습니다.
#!/bin/bash
AllServers=(
"vmkm13, 172.16.39.71"
"vmkm14, 172.16.39.72"
"vmkm15, 172.16.39.84"
"vmkw51, 172.16.39.73"
"vmkw52, 172.16.39.74"
"vmkw53, 172.16.39.75"
"vmkw54, 172.16.39.76"
"vmkw55, 172.16.39.77"
"vmkw56, 172.16.39.78"
"vmkw57, 172.16.39.79"
"vmkw58, 172.16.39.80"
"vmkw59, 172.16.39.81"
"vmkw60, 172.16.39.82"
"vmkw61, 172.16.39.83"
"vmkw62, 172.16.39.85"
"vmkw63, 172.16.39.86"
"vmkw64, 172.16.39.87"
)
for Servers in "${AllServers[@]}"; do
Servername=$(echo "$Servers" | awk -F',' '{ print $1 }')
ServerIP=$(echo "$Servers" | awk -F',' '{ print $2 }')
done
이는 결코 옳지 않습니다. 그러나 데이터를 큰따옴표로 묶은 다음 항목을 쉼표로 구분하면 AWK와 같은 도구를 사용하여 열 항목을 변수로 추출할 수 있습니다. 나는 이것이 매우 해킹적인 접근 방식이라고 말했습니다. 하지만 작동합니다.
답변4
declare -p
이것은 해킹적이지만 typeset -p
배열을 직렬화할 수 있습니다. 이 전략을 사용하여 Bash에서 일련의 직렬화된 배열을 만든 다음 eval
이를 만듭니다. 빈 문자열을 값으로 고려하려면 따옴표를 사용해야 합니다.
# multidimensional array serialized with `declare -p`
# red, yellow, green things
declare -a color_table=(
"$(inner_row=(stop caution go); declare -p inner_row)"
"$(inner_row=(rose tulip clover); declare -p inner_row)"
"$(inner_row=(strawberry banana grape); declare -p inner_row)"
)
이 다차원 배열을 사용하는 방법은 다음과 같습니다.
# using eval, we deserialize the inner_row variable as we loop
echo "=== table ==="
printf '%s\n' "${color_table[@]}"
echo "=== rows ==="
for row in "${color_table[@]}"; do
eval $row
echo "red thing: ${inner_row[0]}"
echo "yellow thing: ${inner_row[1]}"
echo "green thing: ${inner_row[2]}"
done
출력은 다음과 같습니다
=== table ===
declare -a inner_row=([0]="stop" [1]="caution" [2]="go")
declare -a inner_row=([0]="rose" [1]="tulip" [2]="clover")
declare -a inner_row=([0]="strawberry" [1]="banana" [2]="grape")
=== rows ===
red thing: stop
yellow thing: caution
green thing: go
red thing: rose
yellow thing: tulip
green thing: clover
red thing: strawberry
yellow thing: banana
green thing: grape
Zsh 사용자의 경우 배열이 1부터 시작하므로 이 스크립트가 작동하지만 이 예에서는 인덱싱에 0-2를 사용하는 대신 1-3을 사용합니다.