【问题标题】:bash, find the start position of the nth word in a string that has multiple spaces between wordsbash,在单词之间有多个空格的字符串中查找第 n 个单词的起始位置
【发布时间】:2015-12-09 05:33:34
【问题描述】:

在单词之间可能有多个空格的字符串中找到第 n 个单词的起始位置的最简单方法是什么。

我可以通过逐个字符解析轻松地做到这一点,但我认为使用某些 bash 命令可能会有更快、更简单的方法。

子串中可以有多个相等的词和词。

这里第5个单词的开头:

' the cat ate  the  bird'

应该是 20(基于 1)

【问题讨论】:

  • 你能解释一下为什么这是一个 xyproblem。我的主题标题实际上说明了一切,您必须假设由于未指定单词的格式,因此它们可以是任何内容,包括重复和子字符串。
  • @KiloOne 这是 X/Y,因为您要求的算法没有算法解决的问题的上下文。
  • :) 现在如果我知道那是什么意思 :)
  • 它的意思是“请向我们解释这将为您解决哪个问题,因为如果您的其他问题有理智的方法,解决这个问题就是浪费时间。”

标签: bash


【解决方案1】:

使用awk 非常快:

$ awk '{ print index($0, $2); }' <<<'foo bar baz'
4

这给出了第二个单词的从 1 开始的字符索引。将$2 替换为$1 作为第一个单词,将$3 替换为第三个单词,依此类推,或者将$NF 替换为最后一个单词。当第 n 个单词是前面单词之一的子字符串时要小心。

更新基于 Karakfa 的巧妙方法: 如果你的第 n 个单词是前一个单词的子串,那么你需要更加勤奋:

$ cat t
foo bar baz
fobaro bar baz
bar bar baz

$ awk '{ print 1 == index($0, $2) ? 1 : index($0, " "$2)+1; }' < t
4
7
0

$ awk '{ print 1 == index($0, $5) ? 1 : index($0, " "$5)+1; }' <<<' the cat ate  the  bird'
20

根据 KiloOne 对功能的需要进行了更新

function position() {
    local n=${1:?For what column do you want position?}

    awk "{ print 1 == index(\$0, \$$n) ? 1 : index(\$0, \" \"\$$n)+1; }"
}

$ echo 'my cat ate your bird' | position 3
8 

Now available on github as a bashworks module.

【讨论】:

  • 尝试“foobar bar baz”作为输入。
  • 我认为这会解决它awk '{print index($0, " "$2)}',因为空格不是任何单词的一部分。
  • @karakfa 这非常聪明!我认为你是对的。
  • 第一个字除外!但无论如何这都是微不足道的。
  • 删除-1,因为它指向基于0的索引空间。
【解决方案2】:

awk 来救援!

如果这是一个 xy 问题,并且您确实想在找到位置后提取第 n 个字段,您可以尝试以下操作。例如对于 n=4。

$ echo "this is a   long    string  with     non-uniform    spacing"  | awk '{print $4}'

long

$ echo ... | tr -s ' ' '\t' | cut -f4

long

【讨论】:

  • 我要第n个字段的位置
猜你喜欢
  • 2015-04-08
  • 2019-02-11
  • 1970-01-01
  • 2011-12-26
  • 1970-01-01
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多