bash 쉘에서 1개 이상의 공백으로 구분된 문자열을 여러 문자열로 분할하려면 어떻게 해야 합니까?
나는 적어도 두 단어 사이에 한 칸씩 많은 단어를 포함하는 문자열을 가지고 있다.문자열을 개별 단어로 분할하여 루프할 수 있도록 하려면 어떻게 해야 합니까?
문자열은 인수로 전달됩니다.예.${2} == "cat cat file"
어떻게 루프를 통과하지?
또한 문자열에 공백이 있는지 어떻게 확인할 수 있습니까?
개별 요소에 액세스할 수 있도록 어레이로 변환하는 것이 좋습니다.
sentence="this is a story"
stringarray=($sentence)
이제 개별 요소에 직접 액세스할 수 있습니다(0부터 시작).
echo ${stringarray[0]}
또는 다시 문자열로 변환하여 루프합니다.
for i in "${stringarray[@]}"
do
:
# do whatever on $i
done
물론 스트링을 통해 직접 루프하는 것은 이전에도 답한 적이 있지만, 이 답변에는 나중에 사용하기 위해 개별 요소를 추적하지 않는 단점이 있습니다.
for i in $sentence
do
:
# do whatever on $i
done
Bash 어레이 레퍼런스도 참조해 주세요.
문자열 변수를 전달하려고 했습니까?for
예를 들어, Bash는 자동으로 공백으로 분할됩니다.
sentence="This is a sentence."
for word in $sentence
do
echo $word
done
This
is
a
sentence.
BASH 3 이상에서 가장 쉽고 안전한 방법은 다음과 같습니다.
var="string to split"
read -ra arr <<<"$var"
(어디서)arr
는 문자열의 분할 부분을 차지하는 배열입니다.또는 입력에 새로운 행이 있을 수 있고 첫 번째 행보다 더 많은 행이 필요할 수 있습니다.
var="string to split"
read -ra arr -d '' <<<"$var"
(스페이스에 주의해 주세요.-d ''
; 생략할 수 없습니다). 단, 이 경우 에서 예기치 않은 새로운 행이 표시될 수 있습니다.<<<"$var"
(이것에 의해, 마지막에 LF가 암묵적으로 추가되기 때문에).
예:
touch NOPE
var="* a *"
read -ra arr <<<"$var"
for a in "${arr[@]}"; do echo "[$a]"; done
예상 출력
[*]
[a]
[*]
이 솔루션(이전의 모든 솔루션과는 대조적으로)은 예기치 않게 제어 불가능한 셸글로빙이 발생하기 쉽지는 않기 때문입니다.
또, 다음과 같이, IFS 의 모든 기능을 이용할 수 있습니다.
예:
IFS=: read -ra arr < <(grep "^$USER:" /etc/passwd)
for a in "${arr[@]}"; do echo "[$a]"; done
출력은 다음과 같습니다.
[tino]
[x]
[1000]
[1000]
[Valentin Hilbig]
[/home/tino]
[/bin/bash]
보시는 바와 같이 공간도 이 방법으로 보존할 수 있습니다.
IFS=: read -ra arr <<<' split : this '
for a in "${arr[@]}"; do echo "[$a]"; done
출력
[ split ]
[ this ]
주의하시기 바랍니다.IFS
BASH 에서는, 그 자체가 대상입니다.테스트도 대상입니다.이것에 관한 몇개의 흥미로운 토픽이 있습니다.
unset IFS
: SPC, TAB, NL 및 온라인 시작 및 종료 실행을 무시합니다.IFS=''
: 필드를 구분하지 않고 모든 것을 읽습니다.IFS=' '
: SPC 실행(및 SPC만 해당)
마지막 예:
var=$'\n\nthis is\n\n\na test\n\n'
IFS=$'\n' read -ra arr -d '' <<<"$var"
i=0; for a in "${arr[@]}"; do let i++; echo "$i [$a]"; done
출력
1 [this is]
2 [a test]
하는 동안에
unset IFS
var=$'\n\nthis is\n\n\na test\n\n'
read -ra arr -d '' <<<"$var"
i=0; for a in "${arr[@]}"; do let i++; echo "$i [$a]"; done
출력
1 [this]
2 [is]
3 [a]
4 [test]
BTW:
익숙하지 않은 경우
$'ANSI-ESCAPED-STRING'
익숙해져요. 시간 절약이 되죠.포함하지 않는 경우
-r
(예:read -a arr <<<"$var"
그러면 read는 백슬래시가 이스케이프됩니다.이것은 독자를 위한 연습으로 남겨져 있다.
두 번째 질문:
나는 을 한다.case
케이스를 할 수 있기 는 첫 일치만을 해, 폴 필요한 는, 복수의 「Multiple」(「Multiple」)를 합니다).case
이치노이러한 요구는 매우 빈번하게 발생합니다(이러한 요구는,
case "$var" in
'') empty_var;; # variable is empty
*' '*) have_space "$var";; # have SPC
*[[:space:]]*) have_whitespace "$var";; # have whitespaces like TAB
*[^-+.,A-Za-z0-9]*) have_nonalnum "$var";; # non-alphanum-chars found
*[-+.,]*) have_punctuation "$var";; # some punctuation chars found
*) default_case "$var";; # if all above does not match
esac
따라서 다음과 같이 SPC를 검사하도록 반환 값을 설정할 수 있습니다.
case "$var" in (*' '*) true;; (*) false;; esac
★★★★case
보통 regex 시퀀스보다 읽기 쉽고 Shell 메타캐릭터 덕분에 모든 요구의 99%를 매우 잘 처리할 수 있습니다.
내장된 쉘을 사용하면 됩니다.예를들면,
set $text
그 후 $text 내의 개별 단어는 $1, $2, $3 등이 됩니다.견고성을 위해 보통 다음과 같은 작업을 수행합니다.
set -- junk $text
shift
$text가 비어 있거나 대시로 시작하는 경우를 처리합니다.예를 들어 다음과 같습니다.
text="This is a test"
set -- junk $text
shift
for word; do
echo "[$word]"
done
이 인쇄물은
[This]
[is]
[a]
[test]
$ echo "This is a sentence." | tr -s " " "\012"
This
is
a
sentence.
공간을 확인하려면 grep를 사용합니다.
$ echo "This is a sentence." | grep " " > /dev/null
$ echo $?
0
$ echo "Thisisasentence." | grep " " > /dev/null
$ echo $?
1
echo $WORDS | xargs -n1 echo
그러면 모든 단어가 출력되므로 나중에 적합하다고 판단되는 대로 목록을 처리할 수 있습니다.
(A) 문장을 해당 단어로 분할하려면(공백으로 구분됨) 기본 IFS를 사용하면 됩니다.
array=( $string )
다음 스니펫을 실행하는 예
#!/bin/bash
sentence="this is the \"sentence\" 'you' want to split"
words=( $sentence )
len="${#words[@]}"
echo "words counted: $len"
printf "%s\n" "${words[@]}" ## print array
will 출력
words counted: 8
this
is
the
"sentence"
'you'
want
to
split
할 수 .
★★★★★★★
--이것은 기본적으로 mob의 답변과 동일하지만, 이러한 방법으로 어레이를 보존해 두면, 한층 더 필요하게 됩니다.루프가 1개만 필요한 경우는, 1 행 짧게 하는 그의 회답을 사용할 수 있습니다.
-- 딜리미터에 근거해 문자열을 분할하는 대체 방법에 대해서는, 이 질문을 참조해 주세요.
(B) 문자열 내의 문자를 확인하려면 정규 표현 일치를 사용할 수도 있습니다.
사용할 수 있는 공백 문자가 있는지 확인하는 예:
regex='\s{1,}'
if [[ "$sentence" =~ $regex ]]
then
echo "Space here!";
fi
bash만으로 공간을 확인하는 경우:
[[ "$str" = "${str% *}" ]] && echo "no spaces" || echo "has spaces"
echo foo bar baz | sed 's/ /\n/g'
foo
bar
baz
제 사용 사례에서 가장 좋은 옵션은 다음과 같습니다.
grep -oP '\w+' file
기본적으로 이것은 연속된 공백이 아닌 문자와 일치하는 정규 표현입니다.즉, 모든 유형과 공백의 양이 일치하지 않습니다.-o 파라미터는 각 워드가 다른 행에서 일치하는 것을 출력합니다.
이에 대한 또 다른 견해(Perl 사용):
$ echo foo bar baz | perl -nE 'say for split /\s/'
foo
bar
baz
언급URL : https://stackoverflow.com/questions/1469849/how-to-split-one-string-into-multiple-strings-separated-by-at-least-one-space-in
'source' 카테고리의 다른 글
내보내기 여부와 관계없이 변수 정의 (0) | 2023.04.09 |
---|---|
하나의 UITableViewCell에서 구분선 숨기기 (0) | 2023.04.09 |
IDisposable을 사용하여 Excel Interop 객체 정리 (0) | 2023.04.09 |
Excel VBA - 루프 종료 (0) | 2023.04.09 |
SQL Server 데이터베이스의 모든 데이터 삭제 (0) | 2023.04.09 |