bash中字符串的最后n个单词

时间:2015-02-25 13:06:27

标签: string bash

我有一个包含许多(总数变化)单词的字符串,我需要获得最后10个单词。我该怎么做?我正在看awk,grep和cut但是没有什么真正想到的。

一个例子(尽管在我看来问题很清楚):

aaa bda fdkfj fds fsd ... dsad dsas dsad zrthd shshh

我想要这个字符串的最后10个单词。

同样,未定义初始字符串中的单词总数。

7 个答案:

答案 0 :(得分:4)

只需使用trtailxargs

$ echo "1 2 3 4 5 6 7 8 9 10" | tr ' ' '\n' | tail -5 | xargs -n5
6 7 8 9 10

这会在每行中打印一个单词,以便tail获得所需的数量。然后,xargs“将它们重新合并”在同一行。

你也可以在翻转文本后将awk的NF设置为你想要的值:

$ echo "1 2 3 4 5 6 7 8 9 10" | rev | awk '{NF=5}1' | rev
6 7 8 9 10

答案 1 :(得分:2)

当您尝试在最后找到单词或字符时,最好在正则表达式中使用行结束$

$ echo "aaa bda fdkfj fds fsd bar dsad dsas dsad zrthd shshh" | grep -o '[^[:space:]]\+\([[:space:]]\+[^[:space:]]\+\)\{9\} *$'
bda fdkfj fds fsd bar dsad dsas dsad zrthd shshh

你也可以在sed中使用相同的正则表达式。

$ echo "aaa bda fdkfj fds fsd bar dsad dsas dsad zrthd shshh" | grep -oP '\S+(?:\s+\S+){9} *$'
bda fdkfj fds fsd bar dsad dsas dsad zrthd shshh

答案 2 :(得分:2)

awk中,内置变量NF设置为每行上的字段数(默认为单词)。所以你可以:

echo "${STRING}" | awk '{
    for (i = NF - 9; i <= NF; i++) {printf "%s ", $i}
    printf "\n"
}'

假设你总是至少有10个单词。如果没有,您可以为此添加额外的检查。如果你不想在行尾添加额外的空间,那么就做更多的事情。

答案 3 :(得分:2)

你想要外壳吗?这是纯shell 。没有awk,没有cut,没有sed,没有perl。你不能得到比这更多的销售。 (好吧,我确实使用wc这是一个实用程序而不是Bash shell的一部分,但其他一切都是Bash的一部分。)

FOO="one two three four five six seven eight nine ten eleven twelve thirteen"
set $FOO
((shift=$(wc -w<<<$FOO)-10))
shift $shift
echo $*
  • set设置位置参数。 (命令行参数中的$1$2等)。
  • $(wc -w<<<$FOO)查找参数数量。
  • 我从10中减去该数字,并获得大于10的参数数量。我将其设置为$shift
  • 然后我转移$shift个参数。这留下了我回显的最后十个参数。

  

你真的不需要wc。 $#扩展为设置的位置参数数量。 - gniourf_gniourf

哦,我忘记了。现在,我们有一个纯Bash 答案:

FOO='one two three four five six seven eight nine ten eleven twelve thirteen'
set $FOO
((shift=$#-10))
shift $shift
echo $*

答案 4 :(得分:2)

规范,纯粹的Bash方法是使用read

string='one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen forty two'
read -r -d '' -a array < <(printf '%s\0' "$string")
# Print only ten last words:
printf '%s\n' "${array[*]: -10}"

如果少于10个单词,则最后一次扩展失败,但这很容易修复:

printf '%s\n' "${array[*]:${#array[@]}<10?0:-10}"

答案 5 :(得分:1)

echo $string | perl -lanE 'say join " ", @F[-10..-1]'

答案 6 :(得分:0)

您的字符串:

string="Lorem ipsum dolor sit amet"

使用纯Bash / Shell单线格式的最后四个单词:

echo ${string/${string% * * * *} /}

重复或删除 *以获取更多或更少的单词。

说明
我们使用Shell Parameter Expansion ${parameter/pattern/string}将x词替换为空。模式${str% * * * *} 返回最后4个单词之前的所有内容时,它会从字符串中删除前导Lorem