![쉘 스크립트에서 문자열을 배열로 변환하는 방법](https://linux55.com/image/119017/%EC%89%98%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%97%90%EC%84%9C%20%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84%20%EB%B0%B0%EC%97%B4%EB%A1%9C%20%EB%B3%80%ED%99%98%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95.png)
내가 읽고Bash에서 문자열을 배열로 분할하는 방법그런데 이 질문은 저랑 좀 다른 것 같아서 제 데이터를 활용해서 질문해보겠습니다.
STDIN에서 다음 줄이 있습니다.
(5,[a,b,c,d,e,f,g,h,i,j])
5개가 내 그룹 ID이고 문자는 배열(그룹 데이터)의 값입니다. 그룹 ID를 var에 넣고 문자를 사용할 수 있는 곳에 넣어야 합니다.IFS=',' read -r -a array <<< "$tline"
답변1
bkpIFS="$IFS"
IFS=',()][' read -r -a array <<<"(5,[a,b,c,d,e,f,g,h,i,j])"
echo ${array[@]} ##Or printf "%s\n" ${array[@]}
5 a b c d e f g h i j
IFS="$bkpIFS"
설명하다:
- 먼저 기본/현재를 백업해야 합니다.쉘 IFS그리고
bkpIFS="$IFS"
; 그런 다음 IFS를 구분 기호 집합
,
,(
,)
, 으로 설정합니다 . 이는 입력 문자열이 하나 이상의 구분 기호로 구분될 수 있음]
을[
의미합니다 .IFS=',()]['
다음으로 라인을 읽고 위에서 정의한 IFS를 기반으로 들어오는 입력 문자열에서 호출되는
read -r -a array
배열로 분할합니다.array
여기에 있는 문자열방법. 이 옵션은 입력 시 백슬래시를 확장하지 않도록-r
명령에 지시합니다 .read
\
IFS=',()][' read -a array <<<"(5,[a,b,c,d,e,f,g,h,i,j,\,k])" echo ${array[@]} 5 a b c d e f g h i j ,k
끝을 보아라
,k
이는 옵션read
없이 입력에 백슬래시가 있기 때문에-r
발생합니다 .echo ${array[@]}
배열의 모든 요소를 인쇄하고 있습니다 . 바라보다$*와 $@의 차이점은 무엇인가요?그리고자일스의 대답${array[@]}
거기 에 대한 자세한 내용이 있습니다.printf "%s\n" ${array[@]}
배열 요소를 인쇄하는 다른 방법이 있습니다 .printf "%s\n" ${array[INDEX]}
이제 배열의 특정 요소를 사용하거나 인쇄할 수 있습니다echo ${array[INDEX]}
.IFS
아, 죄송합니다. 쉘에 다시 보고하는 것을 잊었습니다 .IFS="$bkpIFS"
:)
또는 awk
그 split
기능을 사용하십시오.
awk '{split($0,arr,/[][,)(]/)}
END{for (x in arr) printf ("%s ",arr[x]);printf "\n"}' <<<"(5,[a,b,c,d,e,f,g,h,i,j])"
설명하다:
[...]
다시 말하지만, using 함수/[...]/
의 최신 구현에서 지원되는 정규식 상수에 정의된 구분 기호 그룹을 기반으로 전체 입력 줄을 분할합니다 .awk
split
더 읽어보세요기능 섹션에서split()
.다음
END{for (x in arr) printf ("%s ",arr[x]); ...}
으로 배열을 반복arr
하고 해당 값을 인쇄합니다.x
이는 다음을 가리킨다.색인배열arr
요소. 자세히 알아보기awk
BEGIN/END 규칙.
다음으로 측면 리디렉션Bash에서 배열에 요소를 추가/제거하는 방법은 무엇입니까?.
답변2
data=$(tr -d '[]()' | tr ',' '\n')
readarray -t -n 1 group <<<"$data"
readarray -t -s 1 letters <<<"$data"
printf 'group = %s\n' "$group"
printf 'data: %s\n' "${letters[@]}"
이것은 먼저 표준 입력에 도착하는 입력 데이터의 모든 합계를 삭제한 ()
다음 쉼표를 줄 바꿈으로 바꾸고 결과를 에 할당합니다.[]
tr
data
그런 다음 이를 사용하여 readarray
이 데이터를 구문 분석합니다.
첫 번째 호출에서는 첫 번째 항목( 포함)만 읽고 -n 1
이를 변수에 할당합니다 group
.
두 번째 호출에서는 readarray
첫 번째 항목( 포함 -s 1
)을 건너뛰고 나머지 항목을 배열에 할당합니다 letters
.
각 항목에서 -t
실제 개행 문자를 제거합니다.
group
이는 배열이지만 하나의 요소만 포함 하므로 $group
.
$ echo '(5,[a,b,c,d,e,f,g,h,i,j])' | bash ./script.sh
group = 5
data: a
data: b
data: c
data: d
data: e
data: f
data: g
data: h
data: i
data: j
다음은 문자열에 쉼표를 유지하고 readline
이를 사용하여 항목을 구분하지만 어떤 이유로 마지막 요소 letters
끝에 개행 문자가 있습니다.
data=$(tr -d '[]()')
readarray -d, -t -s 1 letters <<<"$data"
printf '>%s<\n' "${letters[@]}"
달리기:
$ echo '(5,[a,b,c,d,e,f,g,h,i,j])' | bash ./script.sh
>a<
>b<
>c<
>d<
>e<
>f<
>g<
>h<
>i<
>j
<
답변3
POSIX적으로:
string='(5,[a,b,c,d,e,f,g,h,i,j])'
set -o noglob
IFS=',['
string=${string#'('}
string=${string%'])'}
set -- $string''
gid=$1; shift 2
printf '%s\n' "gid=$gid; group-data:"
printf ' <%s>\n' "$@"
그룹 데이터 필드의 모든 값(개행 문자 포함)에 대해 작동해야 합니다.
답변4
도구를 사용하여 구두점을 제거 sed
하면 해당 줄에서 숫자와 문자만 얻을 수 있습니다.
a="(5,[a,b,c,d,e,f,g,h,i,j])"
echo $a | sed 's/[[:punct:]]/ /g'
산출:
5 a b c d e f g h i j