문자열을 구분 기호로 분할하여 알 수 없는 부분 수를 생성하는 방법과 결과를 배열로 수집하는 방법은 무엇입니까?

문자열을 구분 기호로 분할하여 알 수 없는 부분 수를 생성하는 방법과 결과를 배열로 수집하는 방법은 무엇입니까?

경로가 포함된 일부 문자열을 처리해야 합니다. /이러한 문자열을 구분 기호로 분할하여 알 수 없는 경로 부분 수를 생성하는 방법 과 궁극적으로 결과 경로 부분을 추출하는 방법은 무엇입니까?

cut분명히 부품 수를 미리 알아야 하고 각 부품을 출력하여 사용하거나 readarray배열 mapfile로 수집할 수 없기 때문에 선택하는 도구는 아닙니다.

답변1

에서 bash단일 문자 구분 기호의 경우 glob 부분을 비활성화한 후 분할+glob 연산자를 사용할 수 있습니다(목록 컨텍스트에서 따옴표가 없는 확장 유지).

string='foo/bar
baz/asd..'

IFS=/
set -o noglob
array=( $string )

string='/foo/'로만 분할된다는 점에 유의하세요 (분할할 때와 동일) . , 및 으로 분할하려면 다음을 수행할 수 있습니다."""foo"string='/foo'"""foo"""

IFS=/
set -o noglob
array=( $string'' )

그래도 string=''0 요소 대신 빈 요소로 분할됩니다.

( zshsplit+glob은 /emulation을 제외하고 따옴표가 없는 확장을 수행하지 않음)에서는 단일 문자 구분 기호로 제한되지 않는 매개변수 확장 플래그를 사용할 수 있습니다.shkshs

array=( ${(s[/])string} )

빈 요소를 제거하거나 다음을 수행합니다.

array=( "${(@s[/])string}" )

빈 요소는 유지됩니다. /foo/그런 다음 이를 로 분할 ""하고 빈 문자열을 0개 요소로 분할합니다 "foo".""

변수에 저장된 구분 기호를 사용하여 분할할 수 있습니다.

array=( "${(@ps[$delimiter])string}" )

p플래그를 사용하면 이스케이프 시퀀스(예: , )를 입력할 수도 있습니다 \0. 이 두 플래그에는 개행에서 분할, NUL에서 분할( 예: , ...의 출력을 분할하는 데 사용할 수 있음 ) \n이라는 단축 플래그가 있습니다 .f0find -print0grep -lZsort -zfiles=( ${(0)"$(grep -lZ pattern -- *)"} )

에서는 zsh다음을 수행할 수도 있습니다.묶다주어진 단일 바이트를 구분 기호로 사용하여 배열 변수를 스칼라 변수로 변환합니다. $pathin 은 zsh실제로 이런 방식으로 구분 기호로 묶인 특수 배열입니다 $PATH( :에서 영감을 얻음 csh). 어떤 변수로도 이 작업을 수행할 수 있습니다. 예를 들면 다음과 같습니다.

typeset -T string array /

배열 과 /연결 - 분리.$string$array

답변2

Bash에서는 read -ahere-string을 사용하여 문자열을 배열로 분할할 수 있습니다.

path=/foo/bar/doo
IFS=/ read -r -a parts <<< "$path"

foo이렇게 하면 4개의 요소(비어 있음) , bar및 가 있는 배열이 제공됩니다 doo.

read개행 문자는 기본적으로 구분 기호로 처리되므로 개행 문자가 포함된 경로에는 작동하지 않습니다 . 이를 방지하려면 를 추가해야 -d ''하지만 문제가 있습니다. 여기서 문자열은 개행 문자를 추가한 다음 마지막 요소에서 제거해야 합니다.

path=$'/path/with/new\nlines'
IFS=/ read -d '' -r -a parts <<< "$path"
parts[-1]=${parts[-1]%$'\n'}

( parts[-1]배열의 마지막 요소를 나타내고 일치하는 후행 ${var%text}값을 제거하도록 확장됩니다.)vartext

또한 경로에 반복되는 슬래시가 포함될 수 있는 경우(예: ) foo//bar, 중간에 빈 배열 요소가 표시됩니다. 마찬가지로 경로가 슬래시로 끝나면 끝에 빈 요소가 표시됩니다.

이를 무시하거나 경로를 전처리하여 제거할 수 있습니다. 이와 같은 방법을 사용하여 중복 슬래시를 제거할 수 있습니다.

shopt -s extglob
path="${path//+('/')/'/'}"

후행 슬래시를 제거하십시오.

shopt -s extglob
path="${path%+('/')}"

//foo그러나 이중 슬래시 는 단일(또는 삼중 등) 슬래시와 달리 경로 이름 시작 부분에

답변3

readarray...각 섹션을 출력하지 않고 다음을 사용할 수 있습니다.mapfile

mapfile/readarray를 사용하여 전체 문자열을 제공하고 구분 기호를 설정하세요. 예를 들어,

str='/f
oo/bar/'

mapfile -d / arr < <(printf '%s' "$str")

declare -p arr

산출:

declare -a arr=([0]="/" [1]=$'f\noo/' [2]="bar/")

관련 정보