bash 在bash脚本中使用空格拆分句子
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26508138/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Split a sentence using space in bash script
提问by Uvais Ibrahim
How can I split a sentence using space, and print from second word onwards?
如何使用空格拆分句子,并从第二个单词开始打印?
For example, if my sentence is Hello World Good Morning
, then I want to print like:
例如,如果我的句子是Hello World Good Morning
,那么我想打印如下:
World
Good
Morning
回答by fedorqui 'SO stop harming'
With cut
:
与cut
:
$ echo "Hello World Good Morning" | cut -d' ' -f2-
World Good Morning
This tells cut
to "cut" (surprisingly) based on d
elimiter space and print from 2nd field up to the end.
这告诉cut
根据d
分隔符空间“剪切”(令人惊讶地)并从第二个字段打印到最后。
With sed
:
与sed
:
$ echo "Hello World Good Morning" | sed 's/^[^ ]* //'
World Good Morning
This gets, from the beginning of the line (^
), a block of characters not containing a space ([^ ]*
) and then a space and replaces it with empty content. This way, the first word is deleted.
这将从行 ( ^
)的开头获取一个不包含空格 ( [^ ]*
)的字符块,然后是一个空格并将其替换为空内容。这样,第一个单词就被删除了。
With pure bash
:
与纯bash
:
$ while IFS=" " read -r _ b; do echo "$b"; done <<< "Hello World Good Morning"
World Good Morning
This sets the field separator to the space and reads the first block in a dummy variable _
and the rest in the variable $b
. Then, it prints $b
.
这会将字段分隔符设置为空格并读取虚拟变量中的第一个块_
和变量中的其余部分$b
。然后,它打印$b
.
Also in awk
, using this Ed Morton's approach:
同样在awk
,使用这个Ed Morton 的方法:
$ echo 'Hello World Good Morning' | awk '{sub(/([^ ]+ +){1}/,"")}1'
World Good Morning
This replaces 1 block of not space characters
+ block of spaces
with an empty string.
这用空字符串替换 1 块not space characters
+ 块spaces
。
回答by Tom Fenech
You can change the record separator to a space in awk and print from the second record onwards:
您可以在 awk 中将记录分隔符更改为空格并从第二条记录开始打印:
$ awk 'NR>1' RS=' ' <<<"Hello World Good Morning"
World
Good
Morning
As pointed out in the comments, there is also an extra blank line at the end of the output. This comes from the newline at the end of the input. If you are using GNU awk, it can be suppressed by setting the record separator to the [[:space:]]
character class:
正如评论中所指出的,输出末尾还有一个额外的空行。这来自输入末尾的换行符。如果您使用的是 GNU awk,则可以通过将记录分隔符设置为[[:space:]]
字符类来抑制它:
$ awk 'NR>1' RS='[[:space:]]' <<<"Hello World Good Morning"
Alternatively, as suggested by fedorqui, you can use printf
instead of echo
to pass the variable to awk:
或者,按照fedorqui 的建议,您可以使用printf
而不是echo
将变量传递给 awk:
printf '%s' 'Hello World Good Morning' | awk 'NR>1' RS=' '
回答by Stephane Chazelas
You can use the split+glob operator:
您可以使用 split+glob 运算符:
sentence="Hello World Good Morning"
set -f # disable the glob part
IFS=" " # split on space characters:
set -- $sentence # apply the split+glob operator
# (leaving a variable expansion unquoted)
Now $1
contains Hello
... $4
contains Morning
.
现在$1
包含Hello
...$4
包含Morning
。
shift 1 # (or just "shift") shifts the positional parameters by 1
printf '%s\n' "$@" # print them
Note that it splits on sequencesof space character and ignores the leading and trailing ones.
请注意,它根据空格字符序列进行拆分,并忽略前导和尾随字符。
The above works in any Bourne-like or POSIX shell except zsh
, not just bash
. With zsh
, there's no implicit split+glob operator upon variable expansion unless in sh emulation. There is an explicit split $=var
and explicit glob $~var
operator. So in zsh
:
在任何类似Bourne或POSIX壳上述作品除zsh
,不只是bash
。使用zsh
,除非在 sh 仿真中,否则变量扩展时没有隐式 split+glob 运算符。有一个显式拆分$=var
和显式 glob$~var
运算符。所以在zsh
:
sentence="Hello World Good Morning"
IFS=" "
set -- $=sentence
shift
printf '%s\n' "$@"
Or:
或者:
words=($=sentence)
printf '%s\n' $words[2,-1]
zsh
also has variable expansion flags including a s
one to split on a given string, and a more consistent way to nest variable expansions than in other shells, so:
zsh
还具有变量扩展标志,包括s
在给定字符串上拆分的标志,以及比其他 shell 更一致的嵌套变量扩展的方法,因此:
$ printf '%s\n' ${${(s: :)sentence}[2,-1]}
World
Good
Morning
回答by glenn Hymanman
A bash-specific example:
一个特定于 bash 的示例:
$ read -ra words <<< "Hello World Good Morning" && printf "%s\n" "${words[@]:1}"
World
Good
Morning
回答by aditsu quit because SE is EVIL
If you want to print on separate lines, you can use tr
:
如果要在单独的行上打印,可以使用tr
:
echo "Hello World Good Morning"|tr ' ' '\n'
To start printing from the 2nd word:
从第二个字开始打印:
echo "Hello World Good Morning"|tr ' ' '\n'|tail -n+2
回答by Avinash Raj
This could be possible through grep only, if your grep supports -P
option.
如果您的 grep 支持-P
选项,这只能通过 grep 实现。
grep -oP '(?:^\S+|(?<!^)\G)\h*\K\S+'
Example:
例子:
$ echo 'Hello World Good Morning' | grep -oP '(?:^\S+|(?<!^)\G)\h*\K\S+'
World
Good
Morning
$ echo 'Hello World Good' | grep -oP '(?:^\S+|(?<!^)\G)\h*\K\S+'
World
Good
$ echo 'Hello World' | grep -oP '(?:^\S+|(?<!^)\G)\h*\K\S+'
World
回答by munkeyoto
$ more good
Hello World Good Morning
$ perl -p -e 's:Hello W:w:g;s: :\n:g' good
world
Good
Morning
perl -p -e # Inline edit
's:Hello W:w:g #look for Hello followed by a space and the letter W, replace it with w
;s: :\n:g' # After you replace it, find any spaces and replace with a newline