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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 11:37:20  来源:igfitidea点击:

Split a sentence using space in bash script

bashshellubuntu

提问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 cutto "cut" (surprisingly) based on delimiter 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 spaceswith 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 printfinstead of echoto 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 $1contains Hello... $4contains 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 $=varand explicit glob $~varoperator. 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]

zshalso has variable expansion flags including a sone 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 -Poption.

如果您的 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