在bash脚本中使用空格拆分句子

时间:2014-10-22 13:05:50

标签: bash shell ubuntu

如何使用空格分割句子,然后从第二个单词开始打印?

例如,如果我的句子是Hello World Good Morning,那么我想打印如下:

World
Good
Morning

7 个答案:

答案 0 :(得分:6)

使用cut

$ echo "Hello World Good Morning" | cut -d' ' -f2-
World Good Morning

这会让cut根据d刻度空间“切断”(令人惊讶地)并从第二个字段打印到最后。


使用sed

$ echo "Hello World Good Morning" | sed 's/^[^ ]* //'
World Good Morning

这从行的开头(^)得到一个不包含空格([^ ]*)的字符块,然后是空格,并用空内容替换它。这样,第一个单词就被删除了。


使用纯bash

$ while IFS=" " read -r _ b; do echo "$b"; done <<< "Hello World Good Morning"
World Good Morning

这会将字段分隔符设置为空格,并读取虚拟变量_中的第一个块,其余部分读取变量$b。然后,它打印$b


同样在awk中,使用此Ed Morton's approach

$ echo 'Hello World Good Morning' | awk '{sub(/([^ ]+ +){1}/,"")}1'
World Good Morning

这会用空字符串替换not space characters + spaces块的1个块。

答案 1 :(得分:5)

您可以将记录分隔符更改为awk中的空格,然后从第二个记录开始打印:

$ awk 'NR>1' RS=' ' <<<"Hello World Good Morning"
World
Good
Morning

正如评论中指出的那样,输出结尾还有一个额外的空白行。这来自输入结束时的换行符。如果您使用的是GNU awk,可以通过将记录分隔符设置为[[:space:]]字符类来抑制它:

$ awk 'NR>1' RS='[[:space:]]' <<<"Hello World Good Morning"

或者,根据fedorqui的建议,您可以使用printf代替echo将变量传递给awk:

printf '%s' 'Hello World Good Morning' | awk 'NR>1' RS=' '

答案 2 :(得分:4)

您可以使用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)

现在$1包含Hello ... $4包含Morning

shift 1 # (or just "shift") shifts the positional parameters by 1
printf '%s\n' "$@" # print them

请注意,它会拆分空格字符的序列,并忽略前导和尾随字符。

以上工作在除zsh之外的任何Bourne-like或POSIX shell中,而不仅仅是bash。对于zsh,除非在sh仿真中,否则在变量扩展时没有隐式的split + glob运算符。有一个显式拆分$=var和显式的glob $~var运算符。所以在zsh

sentence="Hello World Good Morning"
IFS=" "
set -- $=sentence
shift
printf '%s\n' "$@"

或者:

words=($=sentence)
printf '%s\n' $words[2,-1]

zsh也有变量扩展标志,包括要在给定字符串上拆分的s,以及嵌套变量扩展比在其他shell中更一致的方式,所以:

$ printf '%s\n' ${${(s: :)sentence}[2,-1]}
World
Good
Morning

答案 3 :(得分:2)

特定于bash的例子:

$ read -ra words <<< "Hello World Good Morning" && printf "%s\n" "${words[@]:1}"
World
Good
Morning

答案 4 :(得分:0)

$ 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

答案 5 :(得分:0)

如果你的grep支持-P选项,那么只能通过grep实现。

grep -oP '(?:^\S+|(?<!^)\G)\h*\K\S+'

示例:

$ 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

答案 6 :(得分:0)

如果您想在单独的行上打印,可以使用tr

echo "Hello World Good Morning"|tr ' ' '\n'

从第二个字开始打印:

echo "Hello World Good Morning"|tr ' ' '\n'|tail -n+2