小智 273
我喜欢转换为数组,以便能够访问单个元素:
sentence="this is a story"
stringarray=($sentence)
Run Code Online (Sandbox Code Playgroud)
现在你可以直接访问各个元素(从0开始):
echo ${stringarray[0]}
Run Code Online (Sandbox Code Playgroud)
或转换回字符串以循环:
for i in "${stringarray[@]}"
do
:
# do whatever on $i
done
Run Code Online (Sandbox Code Playgroud)
当然,之前直接循环遍历字符串,但是这个答案的缺点是不能跟踪单个元素供以后使用:
for i in $sentence
do
:
# do whatever on $i
done
Run Code Online (Sandbox Code Playgroud)
另请参见Bash阵列参考.
mob*_*mob 259
您是否尝试将字符串变量传递给for循环?例如,Bash将自动拆分空白.
sentence="This is a sentence."
for word in $sentence
do
echo $word
done
Run Code Online (Sandbox Code Playgroud)
This
is
a
sentence.
Run Code Online (Sandbox Code Playgroud)
Ide*_*lic 84
只需使用内置的"set"shell.例如,
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]
Tin*_*ino 65
BASH 3及以上版本中最简单,最安全的方法是:
var="string to split"
read -ra arr <<<"$var"
Run Code Online (Sandbox Code Playgroud)
(arr获取字符串的拆分部分的数组在哪里),或者,如果输入中可能有换行符,并且您想要的不仅仅是第一行:
var="string to split"
read -ra arr -d '' <<<"$var"
Run Code Online (Sandbox Code Playgroud)
(请注意空格-d '',它不能被遗漏),但这可能会给你一个意想不到的换行符<<<"$var"(因为这会隐含地在最后添加一个LF).
例:
touch NOPE
var="* a *"
read -ra arr <<<"$var"
for a in "${arr[@]}"; do echo "[$a]"; done
Run Code Online (Sandbox Code Playgroud)
输出预期的
[*]
[a]
[*]
Run Code Online (Sandbox Code Playgroud)
因为这个解决方案(与此前的所有解决方案相比)不容易出现意外且通常无法控制的shell globbing.
这也为您提供了您可能想要的IFS的全部功能:
例:
IFS=: read -ra arr < <(grep "^$USER:" /etc/passwd)
for a in "${arr[@]}"; do echo "[$a]"; done
Run Code Online (Sandbox Code Playgroud)
输出类似于:
[tino]
[x]
[1000]
[1000]
[Valentin Hilbig]
[/home/tino]
[/bin/bash]
Run Code Online (Sandbox Code Playgroud)
如您所见,空间也可以通过这种方式保留:
IFS=: read -ra arr <<<' split : this '
for a in "${arr[@]}"; do echo "[$a]"; done
Run Code Online (Sandbox Code Playgroud)
输出
[ split ]
[ this ]
Run Code Online (Sandbox Code Playgroud)
请注意,IFSBASH 中的处理是一个独立的主题,所以你的测试,一些有趣的主题:
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
Run Code Online (Sandbox Code Playgroud)
输出
1 [this is]
2 [a test]
Run Code Online (Sandbox Code Playgroud)
而
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
Run Code Online (Sandbox Code Playgroud)
输出
1 [this]
2 [is]
3 [a]
4 [test]
Run Code Online (Sandbox Code Playgroud)
BTW:
如果你不习惯$'ANSI-ESCAPED-STRING'习惯,那就省时了.
如果你不包括-r(比如in read -a arr <<<"$var")那么read会做反斜杠转义.这留给读者练习.
对于第二个问题:
为了测试字符串中的某些东西,我通常会坚持case,因为这可以同时检查多个案例(注意:case只执行第一个匹配,如果你需要使用falllce 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
Run Code Online (Sandbox Code Playgroud)
所以你可以设置返回值来检查SPC,如下所示:
case "$var" in (*' '*) true;; (*) false;; esac
Run Code Online (Sandbox Code Playgroud)
为什么case?因为它通常比正则表达式序列更具可读性,并且由于Shell元字符,它可以很好地处理所有需求的99%.
DVK*_*DVK 42
$ echo "This is a sentence." | tr -s " " "\012"
This
is
a
sentence.
Run Code Online (Sandbox Code Playgroud)
要检查空格,请使用grep:
$ echo "This is a sentence." | grep " " > /dev/null
$ echo $?
0
$ echo "Thisisasentence." | grep " " > /dev/null
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)
Luc*_*one 16
(A)要将句子分成单词(空格分隔),您只需使用默认的IFS即可
array=( $string )
Run Code Online (Sandbox Code Playgroud)
运行以下代码段的示例
#!/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
Run Code Online (Sandbox Code Playgroud)
将输出
words counted: 8
this
is
the
"sentence"
'you'
want
to
split
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,您也可以使用单引号或双引号而没有任何问题
注意:
- 这与mob的答案基本相同,但是通过这种方式您可以存储数组以满足任何进一步的需求.如果你只需要一个循环,你可以使用他的答案,这是一行更短:)
- 请参考这个问题,以获得基于分隔符拆分字符串的替代方法.
(B)要检查字符串中的字符,您还可以使用正则表达式匹配.
检查是否存在可以使用的空格字符的示例:
regex='\s{1,}'
if [[ "$sentence" =~ $regex ]]
then
echo "Space here!";
fi
Run Code Online (Sandbox Code Playgroud)
Ále*_*lex 12
echo $WORDS | xargs -n1 echo
Run Code Online (Sandbox Code Playgroud)
这会输出每个单词,之后您可以根据需要处理该列表。
仅使用bash检查空格:
[[ "$str" = "${str% *}" ]] && echo "no spaces" || echo "has spaces"
Run Code Online (Sandbox Code Playgroud)